diff --git a/Dockerfile b/Dockerfile index 96dd382..02619ef 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ COPY . /var/www/echoIP ADD ./conf/docker/init.sh / RUN apk --update add --no-cache nginx curl nodejs php7 php7-fpm php7-json php7-iconv php7-sqlite3 php7-openssl php7-mbstring && \ mkdir -p /run/nginx && touch /run/nginx/nginx.pid && \ - cp /var/www/echoIP/conf/nginx/docker.conf /etc/nginx/echoip.conf && \ + cp /var/www/echoIP/conf/docker/ip.conf /etc/nginx/echoip.conf && \ cp -f /var/www/echoIP/conf/docker/nginx.conf /etc/nginx/nginx.conf && \ cp /var/www/echoIP/conf/docker/init.sh / && \ sed -i '$i\0\t0\t*\t*\t*\t/var/www/echoIP/backend/qqwryUpdate.sh' /var/spool/cron/crontabs/root diff --git a/README.md b/README.md index 43756fa..6c29329 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ # echoIP +![license](https://img.shields.io/badge/license-MIT-orange.svg) + +![version](https://img.shields.io/badge/version-v1.3-brightgreen.svg) + +![total-lines](https://img.shields.io/tokei/lines/github/dnomd343/echoIP) + > 显示客户端IP、查询IP详细信息 + 获取IP地址的AS、地址、ISP、网段等详细信息,支持IPv4与IPv6地址。 @@ -10,7 +16,7 @@ + 数据来自多个上游服务整合处理,包括在线API与离线数据库,同时支持命令行与网页端查询方式。 -## 如何使用 +## 使用方法 ### 命令行模式 @@ -34,6 +40,8 @@ shell> curl ip.343.re/8.8.8.8 ![echoIP-cli](https://pic.dnomd343.top/images/X4F.png) +更多使用方法可见[命令列表](./docs/cmd-list.md) + ### 网页访问模式 你可以直接在 [https://ip.343.re](https://ip.343.re) 或 [https://ip.dnomd343.top](https://ip.dnomd343.top) 上进行查询,或者将项目部署到自己的服务器上。 @@ -48,303 +56,26 @@ shell> curl ip.343.re/8.8.8.8 + 双击显示框空白处,将会弹出一个二维码,扫描可以直达当前页面。 -## 如何部署 - -> 如果想在自己域名下建立本服务,可按如下方式部署 - -### Docker方式(推荐) - -echoIP支持Docker容器部署,在[Docker Hub](https://hub.docker.com/repository/docker/dnomd343/echoip)可获取已构建的镜像。 - -确定你的服务器上有Docker环境 - -``` -shell> docker -v -···Docker版本信息··· -``` - -启动容器并映射端口 - -``` -# 映射容器服务到宿主机1601端口 -shell> docker run -d --name echoip -p 1601:1601 dnomd343/echoip -``` - -测试容器是否正常工作 - -``` -shell> curl 127.0.0.1:1601/8.8.8.8 -···8.8.8.8的详细信息··· -``` - -配置Nginx反向代理 - -``` -# 进入Nginx配置目录 -shell> cd /etc/nginx/conf.d -shell> vim ip.conf -··· -``` - -写入配置文件 - -``` -server { - listen 80; - listen [::]:80; - server_name ip.343.re; # 改为自己的域名 - location / { - if ($http_user_agent !~* (curl|wget)) { - return 301 https://$server_name$request_uri; - } - proxy_set_header X-Real-IP $remote_addr; - proxy_pass http://127.0.0.1:1601; - } -} - -server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name ip.343.re; # 改为自己的域名 - ssl_certificate /etc/ssl/certs/343.re/fullchain.pem; # 改为自己的证书 - ssl_certificate_key /etc/ssl/certs/343.re/privkey.pem; - - gzip on; - gzip_buffers 32 4K; - gzip_comp_level 6; - gzip_min_length 100; - gzip_types application/javascript text/css text/xml; - gzip_disable "MSIE [1-6]\."; - gzip_vary on; - - location / { - proxy_set_header X-Real-IP $remote_addr; - proxy_pass http://127.0.0.1:1601; - } -} -``` - -重启Nginx服务 - -``` -shell> nginx -s reload -``` - -### 常规方式 - -首先拉取仓库到你的服务器上,这里以 `/var/www/echoIP` 为例 - -``` -shell> cd /var/www -shell> git clone https://github.com/dnomd343/echoIP.git -Cloning into 'echoIP'... -··· -Unpacking objects: 100% ··· done. -``` - -确定你的服务器上有PHP环境、Nodejs环境,同时有 `curl` 与 `wget` 工具 - -``` -shell> php -v -···PHP版本信息··· - -shell> node -v -···Nodejs版本信息··· - -shell> curl --version -···curl版本信息··· - -shell> wget --version -···wget版本信息··· -``` - -开启纯真IP库解析服务 - -``` -shell> cd /var/www/echoIP/backend/qqwryFormat -# 默认端口为1602,注意不要重复开启 -shell> ./start.sh -``` - -配置网页服务器代理,需要额外占用除80与443之外的一个端口,默认为TCP/1601,可按需修改 - -``` -# 进入nginx配置目录 -shell> cd /etc/nginx/conf.d - -# 从代码仓库复制配置文件 -shell> cp /var/www/echoIP/conf/nginx/ip.conf ./ +## 部署教程 -# 修改配置文件,将ip.343.re改为需要部署的域名 -shell> vim ip.conf -··· -``` +> 如果想在自己域名下建立echoIP服务,可按如下方式部署 -重启Nginx服务 +[容器部署方式(推荐)](./docs/setup-docker.md) -``` -shell> nginx -s reload -``` +[常规部署方式](./docs/setup.md) -### 特殊情况 +[CDN注意事项](./docs/cdn.md) -在一些情况下,可能Nginx无法直接监听80与443端口,而是通过前置服务转发到指定端口,这种情况下配置文件需要稍加改动,同时前置服务器应开启 `Proxy Protocol` 支持。 - -``` -# http流量转发到TCP/81端口 -server { - listen 81 proxy_protocol; - listen [::]:81 proxy_protocol; - server_name ip.343.re; # 改为自己的域名 - location / { - if ($http_user_agent !~* (curl|wget)) { - return 301 https://$server_name$request_uri; - } - proxy_set_header X-Real-IP $proxy_protocol_addr; - proxy_pass http://127.0.0.1:1601; - } -} - -# https流量转发到TCP/444端口 -server { - listen 444 ssl http2 proxy_protocol; - listen [::]:444 ssl http2 proxy_protocol; - server_name ip.343.re; # 改为自己的域名 - ssl_certificate /etc/ssl/certs/343.re/fullchain.pem; # 改为自己的证书 - ssl_certificate_key /etc/ssl/certs/343.re/privkey.pem; - - gzip on; - gzip_buffers 32 4K; - gzip_comp_level 6; - gzip_min_length 100; - gzip_types application/javascript text/css text/xml; - gzip_disable "MSIE [1-6]\."; - gzip_vary on; - - location / { - proxy_set_header X-Real-IP $proxy_protocol_addr; - proxy_pass http://127.0.0.1:1601; - } -} -``` +[Proxy Protocol支持](./docs/setup-proxy-protocol.md) ## 开发资料 -### Docker容器 +[容器构建](./docs/docker.md) -交叉构建多架构镜像 - -``` -shell> docker buildx build -t dnomd343/echoip --platform="linux/amd64,linux/arm64,linux/386,linux/arm/v7" https://github.com/dnomd343/echoIP.git#master --push -``` - -制作echoIP镜像 - -``` -shell> docker build -t echoip https://github.com/dnomd343/echoIP.git#master -``` - -启动容器 - -``` -shell> docker run -d --name echoip -p 1601:1601 echoip -``` - -进入容器调试 - -``` -shell> docker exec -it echoip sh -``` - -### 部分接口 - -1. echoIP支持在URL中指定查询目标IP,格式形如 `https://ip.343.re?ip=1.2.3.4`,访问时自动显示该IP地址的信息。 - -2. echoIP后端支持返回当前版本信息,接口位于 `/version` 下,若请求来自命令行,则返回可视化格式,否则返回JSON数据。 - -``` -shell> curl ip.343.re/version -echoip -> v1.1 -qqwry.dat -> 2021-04-21 -ipip.net -> 2019-07-03 +[开发接口](./docs/interface.md) -shell> curl https://ip.343.re/version --user-agent 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.72 Safari/537.36 Edg/90.0.818.42' -{"echoip":"v1.1","qqwry":"20210421","ipip":"20190703"} -``` - -3. echoIP后端统一接口为 `/query`,可请求以下参数 - -``` -error -> 请求出错 -version -> 获取版本数据 -cli -> 来自命令行下的请求 -justip -> 仅查询IP地址 -ip -> 请求指定IP的数据 -``` - -示例 - -``` -shell> curl "ip.343.re/query?justip=true" -{"ip":"116.57.98.121"} - -shell> curl "ip.343.re/query?justip=true&cli=true" -116.57.98.124 - -shell> curl "ip.343.re/query?cli=true&ip=7.7.7.7" -IP: 7.7.7.7 -AS: AS8003 -City: Atlantic City -Region: New Jersey -Country: US - United States(美国) -Timezone: America/New_York -Location: 39.3642,-74.4231 -ISP: Global Resource Systems, LLC -Scope: 7.0.0.0/8 -Detail: 美国俄亥俄州哥伦布市DoD网络信息中心 -``` - -### ipinfo.io - -在线请求,格式为 `https://ipinfo.io/$IP/json`,返回指定IP对应的信息,形如: - -``` -{ - "ip": "47.242.30.65", - "city": "Kowloon", - "region": "Kowloon City", - "country": "HK", - "loc": "22.3167,114.1833", - "org": "AS45102 Alibaba (US) Technology Co., Ltd.", - "timezone": "Asia/Hong_Kong", - "readme": "https://ipinfo.io/missingauth" -} -``` - -查询代码位于 `backend/ipinfo.php` - -### IPIP.net - -离线数据库,在[官网](https://www.ipip.net/product/ip.html)登录后即可下载,国内可精确到市,格式为ipdb,数据不定期更新。 - -数据库文件位于 `backend/ipipfree.ipdb`, 查询代码位于 `backend/ipip.php` - -### 纯真IP库 - -离线数据库,获取方式及解码原理可以参考[这篇](https://blog.dnomd343.top/qqwry.dat-analyse/)博客,国内定位精度较高,数据每5天更新一次。 - -数据库文件位于 `backend/qqwry.dat`,数据库更新脚本位于 `backend/qqwryUpdate.sh`,查询代码位于 `backend/qqwry.php`,数据解析服务位于 `backend/qqwryFormat/*` - -Docker部署方式中,容器内已经预留了 `qqwry.dat` 的自动升级功能,每天00:00时会运行脚本拉取数据库更新。对于常规部署方式,可以配置 `crontab` 自动执行更新脚本,示例如下 - -``` -# 打开crontab任务列表 -shell> crontab -e -··· -# 添加如下一行,表示每天00:00时自动运行指定脚本 -0 0 * * * /var/www/echoIP/backend/qqwryUpdate.sh -``` +[上游接口](./docs/upstream.md) ## 许可证 -MIT ©2021 [@dnomd343](https://github.com/dnomd343) [@ShevonKuan](https://github.com/ShevonKuan) +MIT ©2021 [@dnomd343](https://github.com/dnomd343) [@ShevonKuan](https://github.com/ShevonKuan) \ No newline at end of file diff --git a/backend/queryInfo.php b/backend/queryInfo.php index 5dbdab7..9d864ba 100644 --- a/backend/queryInfo.php +++ b/backend/queryInfo.php @@ -293,8 +293,8 @@ Format: http(s)://' . $webSite . '{Request_URI} /query?xxx=xxx&xxx=xxx |-> error=true: Show error request. - |-> version=true: Show help message. - |-> help=true: Show version of echoIP and IP database. + |-> version=true: Show version of echoIP and IP database. + |-> help=true: Show help message. |-> gbk=true: Use GBK encoding. |-> qr=true: Show QR code of client IP. |-> justip=true: Only query the client IP. diff --git a/conf/docker/ip.conf b/conf/docker/ip.conf new file mode 100644 index 0000000..2d2530d --- /dev/null +++ b/conf/docker/ip.conf @@ -0,0 +1,44 @@ +server { + listen 1601; + set $my_host 127.0.0.1:1601; + set_real_ip_from 0.0.0.0/0; + real_ip_header X-Real-IP; + + root /var/www/echoIP; + error_page 403 404 = /error.html; + + location ^~ /assets {} + location = /index.html {} + location = /error.html {} + + location = /error { + index error.html; + } + + location = /ua { + if ($http_user_agent ~* (curl|wget)) { + return 200 $http_user_agent\n; + } + default_type application/json; + return 200 $http_user_agent; + } + + location = / { + set $query_param ?justip=true&cli=true; + if ($http_user_agent ~* (curl|wget)) { + proxy_pass http://$my_host/query$query_param; + } + index index.html; + } + + location / { + set $query_param $query_string; + if ($http_user_agent ~* (curl|wget)) { + set $query_param $query_param&cli=true; + } + include fastcgi_params; + fastcgi_pass 127.0.0.1:9000; + fastcgi_param QUERY_STRING $query_param; + fastcgi_param SCRIPT_FILENAME /var/www/echoIP/backend/queryInfo.php; + } +} \ No newline at end of file diff --git a/conf/nginx/docker.conf b/conf/nginx/docker.conf index 2d2530d..12019e2 100644 --- a/conf/nginx/docker.conf +++ b/conf/nginx/docker.conf @@ -1,44 +1,35 @@ -server { - listen 1601; - set $my_host 127.0.0.1:1601; - set_real_ip_from 0.0.0.0/0; - real_ip_header X-Real-IP; - - root /var/www/echoIP; - error_page 403 404 = /error.html; - - location ^~ /assets {} - location = /index.html {} - location = /error.html {} - - location = /error { - index error.html; - } - - location = /ua { - if ($http_user_agent ~* (curl|wget)) { - return 200 $http_user_agent\n; - } - default_type application/json; - return 200 $http_user_agent; - } - - location = / { - set $query_param ?justip=true&cli=true; - if ($http_user_agent ~* (curl|wget)) { - proxy_pass http://$my_host/query$query_param; - } - index index.html; - } - - location / { - set $query_param $query_string; - if ($http_user_agent ~* (curl|wget)) { - set $query_param $query_param&cli=true; - } - include fastcgi_params; - fastcgi_pass 127.0.0.1:9000; - fastcgi_param QUERY_STRING $query_param; - fastcgi_param SCRIPT_FILENAME /var/www/echoIP/backend/queryInfo.php; - } +server { + listen 80; + listen [::]:80; + server_name ip.343.re; # 改为自己的域名 + location / { + if ($http_user_agent !~* (curl|wget)) { + return 301 https://$server_name$request_uri; + } + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_pass http://127.0.0.1:1601; + } +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name ip.343.re; # 改为自己的域名 + ssl_certificate /etc/ssl/certs/343.re/fullchain.pem; # 改为自己的证书 + ssl_certificate_key /etc/ssl/certs/343.re/privkey.pem; + + gzip on; + gzip_buffers 32 4K; + gzip_comp_level 6; + gzip_min_length 100; + gzip_types application/javascript text/css text/xml; + gzip_disable "MSIE [1-6]\."; + gzip_vary on; + + location / { + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_pass http://127.0.0.1:1601; + } } \ No newline at end of file diff --git a/conf/nginx/ip.conf b/conf/nginx/ip.conf index 288837f..e09d538 100644 --- a/conf/nginx/ip.conf +++ b/conf/nginx/ip.conf @@ -73,7 +73,7 @@ server { set $query_param $query_param&cli=true; } include fastcgi_params; - fastcgi_pass 127.0.0.1:9000; + fastcgi_pass 127.0.0.1:9000; # 服务器php-fpm接口 fastcgi_param QUERY_STRING $query_param; fastcgi_param SCRIPT_FILENAME /var/www/echoIP/backend/queryInfo.php; } diff --git a/docs/cdn.md b/docs/cdn.md new file mode 100644 index 0000000..d70ea38 --- /dev/null +++ b/docs/cdn.md @@ -0,0 +1,64 @@ +## CDN注意事项 + +### 转发原始客户端IP + +若HTTP连接中存在 `HTTP_X_FORWARDED_FOR` 参数,echoIP优先选择其作为客户端IP,若不存在该参数则使用与服务器连接的IP地址作为客户端IP。 + +因此CDN服务器必须在转发时附带该参数,绝大多数情况下CDN服务器会默认在其中填入客户端真实IP,但部分CDN服务商可能会自定义一个额外的参数来存放该数据,这种情况需要修改WEB服务器配置,将该参数内容拷贝到`HTTP_X_FORWARDED_FOR` 中。 + +若以上配置出错,可能会导致返回IP地址为CDN服务器IP而非客户端IP,在部署并启用CDN服务后务必测试该问题。 + +### 关闭服务器Gzip压缩 + +由于CDN向服务器请求的动态数据较短,压缩效果不大,而静态资源无需持续回源,开启压缩反而浪费服务器资源,因此无需在服务器上配置GZIP压缩,配置示例如下。 + +``` +server { + listen 80; + listen [::]:80; + server_name ip.dnomd343.top; + location / { + if ($http_user_agent !~* (curl|wget)) { + return 301 https://$server_name$request_uri; + } + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_pass http://127.0.0.1:1601; + } +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name ip.dnomd343.top; + ssl_certificate /etc/ssl/certs/dnomd343.top/fullchain.pem; + ssl_certificate_key /etc/ssl/certs/dnomd343.top/privkey.pem; + location / { + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_pass http://127.0.0.1:1601; + } +} +``` + +但CDN服务对客户端的压缩功能建议启用,如Brotli压缩或Gzip压缩,都支持的情况下优先选择前者。 + +### CDN回源配置 + +CDN源站指向部署了echoIP的服务器,回源HOST使用当前echoIP域名,其DNS解析一般通过CNAME或NS方式指向CDN服务商提供的地址。 + +CDN服务建议开启HTTPS服务,如果支持 `HTTP/2`、 `TLS1.3`、`OCSP Stapling` 等特性建议打开,但务必关闭强制HTTPS模式或HSTS功能,否则命令行请求需带上 `https` 前缀或在curl命令中使用 `-vL` 参数。 + +所有协议配置均为跟随客户端协议回源,若服务器上部署了多个不同主域名的服务,切记开启SNI回源功能。 + +### 关闭HTML优化功能 + +部分CDN服务商提供了文件优化功能,将网页文件进行精简,删去其中空白内容。此处务必关闭HTML优化功能,否则命令行请求可能出现格式错乱,但CSS与JS等的优化可正常开启。 + +### CDN静态文件 + +echoIP的静态文件包括 `/assets/` 目录下所有文件以及 `/error` 页面,其余路径均不建议配置为静态数据。 + +### IPv6地址 + +若CDN支持IPv6服务,建议打开该功能,否则无法查询客户端IPv6地址。 diff --git a/docs/cmd-list.md b/docs/cmd-list.md new file mode 100644 index 0000000..7b5aec1 --- /dev/null +++ b/docs/cmd-list.md @@ -0,0 +1,228 @@ +## echoIP命令列表 + +echoIP使用User-agent判别是否为命令行环境,所有带有 `curl` 或 `wget` 的客户端查询均判别为命令行请求,该方式默认允许基于http的通讯方式,而不产生二次跳转。 + +使用 `/help` 指令可查看命令列表 + +``` +shell> curl ip.343.re/help + +echoIP - v1.3 (https://github.com/dnomd343/echoIP) + +Format: http(s)://ip.343.re{Request_URI} + + / or /ip -> Show client IP. + + /info or /info/ -> Show detail of client IP. + /{ip} or /info/{ip} -> Show detail of {ip}. + + /info/gbk -> Show detail of client IP (use GBK encoding). + /{ip}/gbk or /info/{ip}/gbk -> Show detail of {ip} (use GBK encoding). + + /qr -> Show QR code of client IP (use special unicode characters). + /qr/ -> Show QR code of client IP (use full characters). + /qr/{xx} -> Show QR code of client IP (Use two custom characters). + + /help -> Show help message. + /ua -> Show http user-agent of client. + /version -> Show version of echoIP and IP database. + + /query?xxx=xxx&xxx=xxx + |-> error=true: Show error request. + |-> version=true: Show version of echoIP and IP database. + |-> help=true: Show help message. + |-> gbk=true: Use GBK encoding. + |-> qr=true: Show QR code of client IP. + |-> justip=true: Only query the client IP. + |-> ip={ip}: Query of specified IP. +``` + +`/` 或 `/ip`:查询客户端IP地址。 + +``` +shell> curl ip.343.re +47.242.30.65 +shell> curl ip.343.re/ip +47.242.30.65 +``` + +`/info` 或 `/info/`:查询客户端IP的详细信息。 + +``` +shell> curl ip.343.re/info +IP: 47.242.30.65 +AS: AS45102 +City: Hong Kong +Region: Central and Western +Country: CN - China(中国) +Timezone: Asia/Shanghai +Location: 22.2783,114.1747 +ISP: Alibaba (US) Technology Co., Ltd. +Scope: 47.242.0.0 - 47.244.255.255 +Detail: 香港阿里云 +``` + +`/{ip}` 或 `/info/{ip}`:查询指定IP的详细信息。 + +``` +shell> curl ip.343.re/1.1.1.1 +IP: 1.1.1.1 +AS: AS13335 +City: Miami +Region: Florida +Country: US - United States(美国) +Timezone: America/New_York +Location: 25.7867,-80.1800 +ISP: Cloudflare, Inc. +Scope: 1.1.1.1/32 +Detail: 美国APNIC&CloudFlare公共DNS服务器 + +shell> curl ip.343.re/info/8.8.8.8 +IP: 8.8.8.8 +AS: AS15169 +City: Mountain View +Region: California +Country: US - United States(美国) +Timezone: America/Los_Angeles +Location: 37.4056,-122.0775 +ISP: Google LLC +Scope: 8.8.8.8/32 +Detail: 美国加利福尼亚州圣克拉拉县山景市谷歌公司DNS服务器 +``` + +`/info/gbk`:查询客户端IP的详细信息,效果同 `/info` 或 `/info/`,使用GBK编码输出。 + +`/{ip}/gbk` 或 `/info/{ip}/gbk`:查询指定IP的详细信息,效果同 `/{ip}` 或 `/info/{ip}`,使用GBK编码输出。 + +GBK输出方式用于兼容Window10以下及部分早期版本的CMD,使echoIP返回中文信息不乱码。 + +`/qr`:使用特殊Unicode字符绘制客户端IP的URL二维码。 + +``` +# 该方式在部分命令行下存在错位显示问题 +shell> curl ip.343.re/qr +http://ip.343.re/?ip=47.242.30.65 +█▀▀▀▀▀█ ▀▀ ▄█▀ ▄▀▄ █▀▀▀▀▀█ +█ ███ █ █▄ █▀▀▀▀▄▄█▀█ █ ███ █ +█ ▀▀▀ █ ▀█▀▀▄▀▄ ▄▄██ █ ▀▀▀ █ +▀▀▀▀▀▀▀ ▀▄▀▄▀▄█ ▀▄▀ ▀ ▀▀▀▀▀▀▀ +█▀█▀▄▄▀▄▀▄ ▀▀▄█▀ ▄▀▀▄ █▀▀ █ +▄▀▀▀▀ ▀█ ▄▄▄██ ▄▀▄ █ ▄▀▀▄ +▀▄▀▀ ▀▀█ ▀▄█ ▄ ██▄▀▀▄█ ▀▀▄▄ + █▄ ▄█▀ ▄█ █▄▀▄▄ █▀▀█▄▀█▀▀█▀ + █ ▀▀▄▀ ▄▀▄▄ ▄█ ▄▀██ ▀ ▄█ +▀ ▄▀▀▀▀▀ █▀█ █▄█▀▄▀▀▄ ▄▀█ + ▀▀▀▀▀▀ █▀▄▀██▄ █▄▄█▀▀▀███▄▄ +█▀▀▀▀▀█ ▄ ▀▀▀ ▄ ▀██ ▀ █▀ █▄ +█ ███ █ ▄▀▄▄█ █▄ ██▄▀█▀██ ▀▀▄ +█ ▀▀▀ █ █▄ █ ▀▄▄▀▀ █ ▄▄ ▄▀ +▀▀▀▀▀▀▀ ▀▀ ▀ ▀ ▀ ▀▀ ▀ ▀ ▀ +``` + +`/qr/`:使用满格的Unicode字符绘制客户端IP的URL二维码。 + +``` +# 此方式显示错位几率较低,但是显示面积偏大 +shell> curl ip.343.re/qr/ +http://ip.343.re/?ip=47.242.30.65 +██████████████ ████ ████ ██ ██████████████ +██ ██ ████ ██ ██ ██ ██ +██ ██████ ██ ██ ██████████ ██████ ██ ██████ ██ +██ ██████ ██ ████ ██ ██████ ██ ██ ██████ ██ +██ ██████ ██ ████████ ██ ████ ██ ██████ ██ +██ ██ ██ ██ ██ ████████ ██ ██ +██████████████ ██ ██ ██ ██ ██ ██ ██ ██████████████ + ██ ██ ████ ██ +████████ ██ ██ ████ ████ ████ ██████ ██ +██ ██ ████ ██ ██ ████ ██ ██ ██ ██ + ████████ ████ ████ ██ ██ ████ +██ ██ ██████████ ██ ██ ██ ██ ██ +██ ████ ██████ ██ ██ ████ ████ ██ ████ + ██ ██ ████ ██ ██████ ████ ████ + ██ ████ ██ ██ ██ ████████ ████████████ + ████ ████ ████ ████ ████ ██ ████ ██ ██ + ██ ████ ██ ██ ██ ██████ ██ ██ + ██ ██ ██ ████ ████ ██ ████ ████ +██ ██████████ ██████ ██ ████ ████ ████ + ██ ██ ██ ██████ ██ ██ ██ ██ + ████████████ ████ ██████ ██ ██████████████ + ██ ██ ██████ ████████ ██████████ +██████████████ ██████ ██████ ██ ████ ██ +██ ██ ██ ██ ████ ██ ████ +██ ██████ ██ ██ ██ ██ ████ ██████████ ████ +██ ██████ ██ ██ ██████ ████ ██████ ██ ████ ██ +██ ██████ ██ ██ ██ ██ ████ ██ ██ +██ ██ ████ ██ ████ ██ ████ ██ +██████████████ ████ ██ ██ ██ ████ ██ ██ ██ +``` + +`/qr/{xx}`:使用自定义字符绘制客户端IP的URL二维码。 + +``` +# 此方式在等宽字体下不存在错位问题,但是显示效果较差 +shell> curl ip.343.re/qr/@$ +http://ip.343.re/?ip=47.242.30.65 +@$@$@$@$@$@$@$ @$@$ @$@$ @$ @$@$@$@$@$@$@$ +@$ @$ @$@$ @$ @$ @$ @$ +@$ @$@$@$ @$ @$ @$@$@$@$@$ @$@$@$ @$ @$@$@$ @$ +@$ @$@$@$ @$ @$@$ @$ @$@$@$ @$ @$ @$@$@$ @$ +@$ @$@$@$ @$ @$@$@$@$ @$ @$@$ @$ @$@$@$ @$ +@$ @$ @$ @$ @$ @$@$@$@$ @$ @$ +@$@$@$@$@$@$@$ @$ @$ @$ @$ @$ @$ @$ @$@$@$@$@$@$@$ + @$ @$ @$@$ @$ +@$@$@$@$ @$ @$ @$@$ @$@$ @$@$ @$@$@$ @$ +@$ @$ @$@$ @$ @$ @$@$ @$ @$ @$ @$ + @$@$@$@$ @$@$ @$@$ @$ @$ @$@$ +@$ @$ @$@$@$@$@$ @$ @$ @$ @$ @$ +@$ @$@$ @$@$@$ @$ @$ @$@$ @$@$ @$ @$@$ + @$ @$ @$@$ @$ @$@$@$ @$@$ @$@$ + @$ @$@$ @$ @$ @$ @$@$@$@$ @$@$@$@$@$@$ + @$@$ @$@$ @$@$ @$@$ @$@$ @$ @$@$ @$ @$ + @$ @$@$ @$ @$ @$ @$@$@$ @$ @$ + @$ @$ @$ @$@$ @$@$ @$ @$@$ @$@$ +@$ @$@$@$@$@$ @$@$@$ @$ @$@$ @$@$ @$@$ + @$ @$ @$ @$@$@$ @$ @$ @$ @$ + @$@$@$@$@$@$ @$@$ @$@$@$ @$ @$@$@$@$@$@$@$ + @$ @$ @$@$@$ @$@$@$@$ @$@$@$@$@$ +@$@$@$@$@$@$@$ @$@$@$ @$@$@$ @$ @$@$ @$ +@$ @$ @$ @$ @$@$ @$ @$@$ +@$ @$@$@$ @$ @$ @$ @$ @$@$ @$@$@$@$@$ @$@$ +@$ @$@$@$ @$ @$ @$@$@$ @$@$ @$@$@$ @$ @$@$ @$ +@$ @$@$@$ @$ @$ @$ @$ @$@$ @$ @$ +@$ @$ @$@$ @$ @$@$ @$ @$@$ @$ +@$@$@$@$@$@$@$ @$@$ @$ @$ @$ @$@$ @$ @$ @$ +``` + +`/help`:显示帮助信息。 + +`/ua`:显示客户端User-agent,常在网页端使用。 + +``` +shell> curl ip.343.re/ua +curl/7.29.0 +``` + +`/version`:显示echoIP及IP数据库版本信息。 + +``` +shell> curl ip.343.re/version +echoip -> v1.3 +qqwry.dat -> 2021-07-07 +ipip.net -> 2019-07-03 +``` + +`/query?xxx=xxx&xxx=xxx`:原生查询接口。 + ++ `error=true`:返回错误信息/页面 + ++ `version=true`:显示echoIP及IP数据库版本信息 + ++ `help=true`:显示帮助信息 + ++ `gbk=true`:使用GBK编码 + ++ `qr=true`:显示客户端IP的二维码 + ++ `justip=true`:仅查询客户端IP地址 + ++ `ip={ip}`:查询的目标IP diff --git a/docs/docker.md b/docs/docker.md new file mode 100644 index 0000000..ab6c064 --- /dev/null +++ b/docs/docker.md @@ -0,0 +1,25 @@ +## Docker容器操作 + ++ 交叉构建多架构镜像 + +``` +shell> docker buildx build -t dnomd343/echoip --platform="linux/amd64,linux/arm64,linux/386,linux/arm/v7" https://github.com/dnomd343/echoIP.git#master --push +``` + ++ 制作echoIP镜像 + +``` +shell> docker build -t echoip https://github.com/dnomd343/echoIP.git#master +``` + ++ 启动容器 + +``` +shell> docker run -d --name echoip -p 1601:1601 echoip +``` + ++ 进入容器调试 + +``` +shell> docker exec -it echoip sh +``` diff --git a/docs/interface.md b/docs/interface.md new file mode 100644 index 0000000..102b80d --- /dev/null +++ b/docs/interface.md @@ -0,0 +1,52 @@ +## 开发常用接口 + +1. echoIP支持在URL中指定查询目标IP,格式形如 `https://ip.343.re/?ip=9.9.9.9`,访问时自动显示该IP地址的信息。 + +2. echoIP后端支持返回当前版本信息,接口位于 `/version` 下,若请求来自命令行,则返回可视化格式,否则返回JSON数据。 + +``` +shell> curl ip.343.re/version +echoip -> v1.1 +qqwry.dat -> 2021-04-21 +ipip.net -> 2019-07-03 + +shell> curl https://ip.343.re/version --user-agent 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.72 Safari/537.36 Edg/90.0.818.42' +{"echoip":"v1.1","qqwry":"20210421","ipip":"20190703"} +``` + +3. echoIP后端统一接口为 `/query`,可请求以下参数 + +``` +error -> 请求出错 +version -> 获取版本数据 +cli -> 来自命令行下的请求 +help -> 显示帮助信息 +gbk -> 使用GBK编码 +qr -> 显示二维码 +justip -> 仅查询IP地址 +ip -> 请求指定IP的数据 +``` + +示例 + +``` +shell> curl "ip.343.re/query?justip=true" +{"ip":"116.57.98.121"} + +shell> curl "ip.343.re/query?justip=true&cli=true" +116.57.98.124 + +shell> curl "ip.343.re/query?cli=true&ip=7.7.7.7" +IP: 7.7.7.7 +AS: AS8003 +City: Atlantic City +Region: New Jersey +Country: US - United States(美国) +Timezone: America/New_York +Location: 39.3642,-74.4231 +ISP: Global Resource Systems, LLC +Scope: 7.0.0.0/8 +Detail: 美国俄亥俄州哥伦布市DoD网络信息中心 +``` + +其他接口信息可见[命令列表](./cmd-list.md) diff --git a/docs/setup-docker.md b/docs/setup-docker.md new file mode 100644 index 0000000..8cbd0e6 --- /dev/null +++ b/docs/setup-docker.md @@ -0,0 +1,127 @@ +## Docker部署方式 + +echoIP支持Docker容器部署,在[Docker Hub](https://hub.docker.com/repository/docker/dnomd343/echoip)可获取已构建的镜像。 + +### 1. 配置Docker环境 + +使用以下命令确认Docker环境 + +``` +# 若正常输出则跳过本步 +shell> docker --version +···Docker版本信息··· +``` + +使用以下命令安装Docker + +``` +# Debian系 +shell> sudo apt update && sudo apt upgrade +··· +# RH系 +shell> sudo yum update +··· +# 使用Docker官方脚本安装 +shell> sudo wget -qO- https://get.docker.com/ | bash +··· +# 安装成功后将输出Docker版本信息 +shell> docker --version +Docker version ···, build ··· +``` + +### 2. 启动echoIP + +启动容器并映射端口 + +``` +# 映射容器服务到宿主机1601端口 +shell> docker run -d --name echoip -p 1601:1601 dnomd343/echoip +# 查看容器状态 +shell> docker ps -a +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +48d4b7a644e8 dnomd343/echoip "sh init.sh" 12 seconds ago Created echoip +``` + +测试容器是否正常工作 + +``` +shell> curl 127.0.0.1:1601/8.8.8.8 +···8.8.8.8的详细信息··· +``` + +如果服务器1601端口未配置防火墙,在浏览器输入 `http://服务器IP:1601/` 即可访问echoIP页面 + +常用容器操作命令 + +``` +# 删除容器 +shell> docker rm -f echoip +··· +# 列出全部镜像 +shell> docker images +··· +# 删除镜像 +shell> docker rmi dnomd343/echoip +··· +``` + +### 3. 配置反向代理 + +这里使用Nginx作为示例,其他Web服务原理类似。 + +``` +# 进入Nginx配置目录 +shell> cd /etc/nginx/conf.d +# 下载配置文件 +shell> wget https://raw.githubusercontent.com/dnomd343/echoIP/master/conf/nginx/docker.conf -O ip.conf +# 修改配置文件中域名、证书、端口等信息 +shell> vim ip.conf +``` + +如果你的网络无法正常访问Github,将下述内容写入配置文件亦可。 + +``` +server { + listen 80; + listen [::]:80; + server_name ip.343.re; # 改为自己的域名 + location / { + if ($http_user_agent !~* (curl|wget)) { + return 301 https://$server_name$request_uri; + } + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_pass http://127.0.0.1:1601; + } +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name ip.343.re; # 改为自己的域名 + ssl_certificate /etc/ssl/certs/343.re/fullchain.pem; # 改为自己的证书 + ssl_certificate_key /etc/ssl/certs/343.re/privkey.pem; + + gzip on; + gzip_buffers 32 4K; + gzip_comp_level 6; + gzip_min_length 100; + gzip_types application/javascript text/css text/xml; + gzip_disable "MSIE [1-6]\."; + gzip_vary on; + + location / { + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_pass http://127.0.0.1:1601; + } +} +``` + +重启Nginx服务 + +``` +shell> nginx -s reload +``` + +将配置的域名DNS解析到当前服务器,即可用该域名访问echoIP服务。 \ No newline at end of file diff --git a/docs/setup-proxy-protocol.md b/docs/setup-proxy-protocol.md new file mode 100644 index 0000000..f8cb5a2 --- /dev/null +++ b/docs/setup-proxy-protocol.md @@ -0,0 +1,47 @@ +## Proxy Protocol支持 + +在某些情况下,Nginx无法直接监听80与443端口,而是通过前置服务转发到指定端口,这种情况下配置文件需要稍加改动,同时前置服务器应开启 `Proxy Protocol` 支持。 + +若未配置 `Proxy Protocol` 协议,则Nginx无法得知客户端IP地址,此时所有查询结果均为前置服务器IP地址。 + +Nginx配置文件改动如下 + +``` +# TCP/81端口接收携带Proxy Protocol的http流量 +server { + listen 81 proxy_protocol; + listen [::]:81 proxy_protocol; + server_name ip.343.re; # 改为自己的域名 + location / { + if ($http_user_agent !~* (curl|wget)) { + return 301 https://$server_name$request_uri; + } + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $proxy_protocol_addr; + proxy_pass http://127.0.0.1:1601; + } +} + +# TCP/444端口接收携带Proxy Protocol的https流量 +server { + listen 444 ssl http2 proxy_protocol; + listen [::]:444 ssl http2 proxy_protocol; + server_name ip.343.re; # 改为自己的域名 + ssl_certificate /etc/ssl/certs/343.re/fullchain.pem; # 改为自己的证书 + ssl_certificate_key /etc/ssl/certs/343.re/privkey.pem; + + gzip on; + gzip_buffers 32 4K; + gzip_comp_level 6; + gzip_min_length 100; + gzip_types application/javascript text/css text/xml; + gzip_disable "MSIE [1-6]\."; + gzip_vary on; + + location / { + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $proxy_protocol_addr; + proxy_pass http://127.0.0.1:1601; + } +} +``` diff --git a/docs/setup.md b/docs/setup.md new file mode 100644 index 0000000..01a53b7 --- /dev/null +++ b/docs/setup.md @@ -0,0 +1,176 @@ +## 常规部署方式 + +此方式涉及服务较多,配置较为繁琐且可能存在版本兼容问题,不熟悉Linux操作的用户建议使用[Docker方式](./setup-docker.md)。 + +### 1. 拉取源码 + +首先拉取仓库到服务器上,这里以 `/var/www/echoIP` 为例 + +``` +shell> cd /var/www +shell> git clone https://github.com/dnomd343/echoIP.git +Cloning into 'echoIP'... +··· +Unpacking objects: 100% ··· done. +``` + +### 2. 环境检查 + +确定你的服务器上有PHP环境、Nodejs环境,同时有 `curl` 与 `wget` 工具 + +``` +shell> php -v +···PHP版本信息··· + +shell> node -v +···Nodejs版本信息··· + +shell> curl --version +···curl版本信息··· + +shell> wget --version +···wget版本信息··· +``` + +确认PHP-FPM正常运行 + +``` +shell> systemctl | grep fpm +php7.3-fpm.service loaded active running The PHP 7.3 FastCGI Process Manager +``` + +### 3. 运行数据解析服务 + +``` +# qqwry.dat数据解析服务 +shell> cd /var/www/echoIP/backend/qqwryFormat +# 默认端口为1602,注意不要重复开启 +shell> ./start.sh +``` + +### 4. 配置Web服务 + +配置网页服务器代理,需要额外占用除80与443之外的一个端口,默认为TCP/1601,可按需修改。这里使用Nginx作为示例,其他Web服务原理类似。 + +``` +# 进入nginx配置目录 +shell> cd /etc/nginx/conf.d + +# 从代码仓库复制配置文件 +shell> cp /var/www/echoIP/conf/nginx/ip.conf ./ + +# 修改配置文件中域名、证书、端口等信息 +shell> vim ip.conf +``` + +配置文件内容如下 + +``` +server { + listen 80; + listen [::]:80; + server_name ip.343.re; # 改为自己的域名 + location / { + if ($http_user_agent !~* (curl|wget)) { + return 301 https://$server_name$request_uri; + } + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_pass http://127.0.0.1:1601; + } +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name ip.343.re; # 改为自己的域名 + ssl_certificate /etc/ssl/certs/343.re/fullchain.pem; # 改为自己的证书 + ssl_certificate_key /etc/ssl/certs/343.re/privkey.pem; + + gzip on; + gzip_buffers 32 4K; + gzip_comp_level 6; + gzip_min_length 100; + gzip_types application/javascript text/css text/xml; + gzip_disable "MSIE [1-6]\."; + gzip_vary on; + + location / { + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_pass http://127.0.0.1:1601; + } +} + +server { + listen 127.0.0.1:1601; + set $my_host 127.0.0.1:1601; + set_real_ip_from 0.0.0.0/0; + real_ip_header X-Real-IP; + + root /var/www/echoIP; + error_page 403 404 = /error.html; + + location ^~ /assets {} + location = /index.html {} + location = /error.html {} + + location = /error { + index error.html; + } + + location = /ua { + if ($http_user_agent ~* (curl|wget)) { + return 200 $http_user_agent\n; + } + default_type application/json; + return 200 $http_user_agent; + } + + location = / { + set $query_param ?justip=true&cli=true; + if ($http_user_agent ~* (curl|wget)) { + proxy_pass http://$my_host/query$query_param; + } + index index.html; + } + + location / { + set $query_param $query_string; + if ($http_user_agent ~* (curl|wget)) { + set $query_param $query_param&cli=true; + } + include fastcgi_params; + fastcgi_pass 127.0.0.1:9000; # 服务器php-fpm接口 + fastcgi_param QUERY_STRING $query_param; + fastcgi_param SCRIPT_FILENAME /var/www/echoIP/backend/queryInfo.php; + } +} +``` + +其中PHP-FPM接口在不同系统上不同 + +``` +# RH系一般为本地9000端口 +shell> netstat -tlnp | grep 9000 +tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 783/php-fpm: master +# Debian系一般为sock方式 +shell> ls /var/run/php/ +php7.3-fpm.pid php7.3-fpm.sock +``` + +对应Nginx配置如下 +``` +# RH系 +fastcgi_pass 127.0.0.1:9000; +# Debian系 +fastcgi_pass unix:/var/run/php/php7.3-fpm.sock; +``` + +重启Nginx服务 + +``` +shell> nginx -s reload +``` + +将配置的域名DNS解析到当前服务器,即可用该域名访问echoIP服务。 \ No newline at end of file diff --git a/docs/upstream.md b/docs/upstream.md new file mode 100644 index 0000000..3332b33 --- /dev/null +++ b/docs/upstream.md @@ -0,0 +1,42 @@ +## IP上游查询接口 + +### ipinfo.io + +在线请求,格式为 `https://ipinfo.io/$IP/json`,返回指定IP对应的信息,形如: + +``` +{ + "ip": "47.242.30.65", + "city": "Kowloon", + "region": "Kowloon City", + "country": "HK", + "loc": "22.3167,114.1833", + "org": "AS45102 Alibaba (US) Technology Co., Ltd.", + "timezone": "Asia/Hong_Kong", + "readme": "https://ipinfo.io/missingauth" +} +``` + +查询代码位于 `backend/ipinfo.php` + +### IPIP.net + +离线数据库,在[官网](https://www.ipip.net/product/ip.html)登录后即可下载,国内可精确到市,格式为ipdb,数据不定期更新。 + +数据库文件位于 `backend/ipipfree.ipdb`, 查询代码位于 `backend/ipip.php` + +### 纯真IP库 + +离线数据库,获取方式及解码原理可以参考[这里](https://blog.dnomd343.top/qqwry.dat-analyse/),国内定位精度较高,数据每5天更新一次。 + +数据库文件位于 `backend/qqwry.dat`,数据库更新脚本位于 `backend/qqwryUpdate.sh`,查询代码位于 `backend/qqwry.php`,数据解析服务位于 `backend/qqwryFormat/*` + +Docker部署方式中,容器内已经预留了 `qqwry.dat` 的自动升级功能,每天00:00时会运行脚本拉取数据库更新。对于常规部署方式,可以配置 `crontab` 自动执行更新脚本,示例如下 + +``` +# 打开crontab任务列表 +shell> crontab -e +··· +# 添加如下一行,表示每天00:00时自动运行指定脚本 +0 0 * * * /var/www/echoIP/backend/qqwryUpdate.sh +```