type
Post
status
Published
slug
2019/07/27/1564656217457
summary
nginx+wordpress-docker镜像获取真实IP
tags
Linux
Nginx
category
Linux
icon
password
Property
Dec 9, 2022 02:16 AM
created days

nginx+wordpress-docker镜像获取真实IP

因为想偷懒以及维护的方面、所以就将我的博客 docker 化了、采用了 nginx 在前、apache 在后的架构。在完成了构建以及启动之后、我发现 WP 统计 这个插件获取不到真实的用户IP、导致访问的IP全是 docker 容器的IP。让人好生郁闷。

获取真实IP的方法

nginx 获取真实IP的方法

因为我是使用 nginx 将用户的请求反向代理回送至后端的 wordpress 镜像的,所以最先是拿它下手的,话不多说放配置文件。
## 主配置文件 user root root; worker_processes 4; error_log /www/wwwlogs/nginx_error.log error; pid /var/run/nginx.pid; worker_rlimit_nofile 51200; events { use epoll; worker_connections 51200; multi_accept on; } http { server_tokens off; include mime.types; #include luawaf.conf; include proxy.conf; default_type application/octet-stream; server_names_hash_bucket_size 512; client_header_buffer_size 32k; large_client_header_buffers 4 32k; client_max_body_size 1000m; sendfile on; tcp_nopush on; keepalive_timeout 600; tcp_nodelay on; fastcgi_connect_timeout 600; fastcgi_send_timeout 600; fastcgi_read_timeout 600; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 256k; fastcgi_intercept_errors on; gzip off; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 2; gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml; gzip_vary on; gzip_proxied expired no-cache no-store private auth; gzip_disable "MSIE [1-6]\\."; limit_conn_zone $binary_remote_addr zone=perip:10m; limit_conn_zone $server_name zone=perserver:10m; # set user real ip to remote addr # set_real_ip_from 192.168.0.0/16; set_real_ip_from 172.20.0.0/16; real_ip_header X-Forwarded-For; real_ip_recursive on; #log_format combined_realip; log_format compression '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log on; access_log /www/wwwlogs/nginx_access.log compression; include /etc/nginx/conf.d/*.conf; }
nginx 虚拟主机配置文件
server { listen 80; listen 443 ssl http2; server_name expoli.tech; #SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则 #error_page 404/404.html; #HTTP_TO_HTTPS_START # if ($server_port !~ 443){ # rewrite ^(/.*)$ <https://$host$1> permanent; # } #HTTP_TO_HTTPS_END ssl_certificate /var/www/ssl/www.expoli.tech_nginx/www.expoli.tech.pem; ssl_certificate_key /var/www/ssl/www.expoli.tech_nginx/www.expoli.tech.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; error_page 497 https://$host$request_uri; #SSL-END location / { # 保证获取到真实IP proxy_set_header X-Real-IP $remote_addr; # 真实端口号 proxy_set_header X-Real-Port $remote_port; # X-Forwarded-For 是一个 HTTP 扩展头部。 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 在多级代理的情况下,记录每次代理之前的客户端真实ip proxy_set_header HTTP_X_FORWARDED_FOR $remote_addr; # 获取到真实协议 proxy_set_header X-Forwarded-Proto $scheme; # 真实主机名 proxy_set_header Host $host; # 设置变量 proxy_set_header X-NginX-Proxy true; proxy_pass http://tcy_wp_web:80; proxy_redirect default; # Socket.IO Support proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } access_log on; access_log /www/wwwlogs/expoli.tech.log compression; error_log /www/wwwlogs/expoli.tech.error.log; }

测试

经过测试发现、wordpress 还是无法正常获取到真实IP。按道理来说、已经配置成功了。不知道细心的你发现没有那就是、wordpress 镜像默认是使用 apache 做 web 服务器 的所以现在的情况是、与后端之间存在了两层代理,即 一级代理 nginx;二级代理 apache、之所以后端获取不到是因为还未在 apache 上进行相关配置、将真实IP传递到 REMOTE_ADDR 变量中(wordpress 统计插件默认取REMOTE_ADDR变量的值。
  • 测试结果:
Array ( [HTTP_X_REAL_IP] => 202.***.***.*** // nginx 配置已经生效 [HTTP_X_REAL_PORT] => 10469 [HTTP_X_FORWARDED_PROTO] => http // nginx 配置已经生效 [HTTP_HOST] => expoli.tech // nginx 配置已经生效 [HTTP_X_NGINX_PROXY] => true // nginx 配置已经生效 [HTTP_CONNECTION] => upgrade // nginx 配置已经生效 [HTTP_PRAGMA] => no-cache [HTTP_CACHE_CONTROL] => no-cache [HTTP_UPGRADE_INSECURE_REQUESTS] => 1 [HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 [HTTP_DNT] => 1 ... [SERVER_SOFTWARE] => Apache/2.4.25 (Debian) [SERVER_NAME] => expoli.tech [SERVER_ADDR] => 172.20.0.3 [SERVER_PORT] => 80 [REMOTE_ADDR] => 172.20.0.4 // 依旧是 docker 容器Ip [DOCUMENT_ROOT] => /var/www/html [REQUEST_SCHEME] => http [CONTEXT_PREFIX] => [CONTEXT_DOCUMENT_ROOT] => /var/www/html [SERVER_ADMIN] => webmaster@localhost [SCRIPT_FILENAME] => /var/www/html/info.php [REMOTE_PORT] => 40286

配置 apache 以获取用户真实IP

经过多方搜集尝试,了解到 apache2.4提供了自带的remoteip模块可以实现获取真实ip。
/etc/apache2/mods-available 文件夹内的 remoteip.load 复制到 /etc/apache2/mods-enabled/ 文件目录下,并新建配置文件 remoteip.conf
注意:因为考虑到容器大小、所以镜像内并没有集成编辑器、需要临时安装、而且容器一旦删除、已经安装的软件也会没有、不过咱们现在只是做个测试、可以直接安装进行更改测试。
apt-get update apt-get install nano -y
  • remoteip.load
# cat remoteip.load LoadModule remoteip_module /usr/lib/apache2/modules/mod_remoteip.so
  • remoteip.conf
# remoteip.conf RemoteIPHeader X-Forwarded-For RemoteIPProxiesHeader X-Forwarded-By
  • 测试结果
Array ( [HTTP_X_REAL_IP] => 202.***.***.*** [HTTP_X_REAL_PORT] => 10469 [HTTP_X_FORWARDED_PROTO] => http [HTTP_HOST] => expoli.tech [HTTP_X_NGINX_PROXY] => true [HTTP_CONNECTION] => upgrade [HTTP_PRAGMA] => no-cache [HTTP_CACHE_CONTROL] => no-cache [HTTP_UPGRADE_INSECURE_REQUESTS] => 1 [HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 [HTTP_DNT] => 1 ... [SERVER_SOFTWARE] => Apache/2.4.25 (Debian) [SERVER_NAME] => expoli.tech [SERVER_ADDR] => 172.20.0.3 [SERVER_PORT] => 80 [REMOTE_ADDR] => 202.***.***.*** // 成功获取到真实IP [DOCUMENT_ROOT] => /var/www/html [REQUEST_SCHEME] => http [CONTEXT_PREFIX] => [CONTEXT_DOCUMENT_ROOT] => /var/www/html [SERVER_ADMIN] => webmaster@localhost [SCRIPT_FILENAME] => /var/www/html/info.php [REMOTE_PORT] => 40286 [GATEWAY_INTERFACE] => CGI/1.1 [SERVER_PROTOCOL] => HTTP/1.1 [REQUEST_METHOD] => GET ... }

修改 docker-compose.yaml 配置文件

1. 查看相关配置文件的路径

docker exec -it $your_container_name /etc/apache2/ total 88 drwxr-xr-x 1 root root 4096 Jun 27 23:44 . drwxr-xr-x 1 root root 4096 Jul 27 11:24 .. -rw-r--r-- 1 root root 7224 Apr 2 19:05 apache2.conf drwxr-xr-x 1 root root 4096 Jun 27 23:44 conf-available drwxr-xr-x 1 root root 4096 Jun 27 23:44 conf-enabled -rw-r--r-- 1 root root 1924 Jun 27 23:44 envvars -rw-r--r-- 1 root root 31063 Nov 3 2018 magic drwxr-xr-x 1 root root 4096 Jul 3 20:52 mods-available # 可用模块目录 drwxr-xr-x 1 root root 4096 Jul 27 11:24 mods-enabled # 已启用模块目录 -rw-r--r-- 1 root root 320 Nov 3 2018 ports.conf drwxr-xr-x 2 root root 4096 Jun 27 23:44 sites-available drwxr-xr-x 2 root root 4096 Jun 27 23:44 sites-enabled

2. 查看已启用模块配置文件夹

从下面可以看出启用模块的方式就是创建一个链接、将 mods-available 内的文件链接至 mods-enabled 文件夹、所以我们若想启用 remoteip 模块、只需将 remoteip.conf remoteip.load 文件放入即可。
docker exec -it $your_container_name /bin/bash cd /etc/apache2/mods-enabled ls -al total 20 drwxr-xr-x 1 root root 4096 Jul 27 11:24 . drwxr-xr-x 1 root root 4096 Jun 27 23:44 .. lrwxrwxrwx 1 root root 36 Jun 27 23:44 access_compat.load -> ../mods-available/access_compat.load lrwxrwxrwx 1 root root 28 Jun 27 23:44 alias.conf -> ../mods-available/alias.conf lrwxrwxrwx 1 root root 28 Jun 27 23:44 alias.load -> ../mods-available/alias.load ... lrwxrwxrwx 1 root root 32 Jun 27 23:44 autoindex.conf -> ../mods-available/autoindex.conf lrwxrwxrwx 1 root root 32 Jun 27 23:44 autoindex.load -> ../mods-available/autoindex.load lrwxrwxrwx 1 root root 30 Jun 27 23:44 deflate.conf -> ../mods-available/deflate.conf lrwxrwxrwx 1 root root 30 Jun 27 23:44 deflate.load -> ../mods-available/deflate.load ... lrwxrwxrwx 1 root root 34 Jun 27 23:44 mpm_prefork.conf -> ../mods-available/mpm_prefork.conf lrwxrwxrwx 1 root root 34 Jun 27 23:44 mpm_prefork.load -> ../mods-available/mpm_prefork.load lrwxrwxrwx 1 root root 34 Jun 27 23:44 negotiation.conf -> ../mods-available/negotiation.conf lrwxrwxrwx 1 root root 34 Jun 27 23:44 negotiation.load -> ../mods-available/negotiation.load lrwxrwxrwx 1 root root 27 Jul 3 20:52 php7.load -> ../mods-available/php7.load ... lrwxrwxrwx 1 root root 29 Jun 27 23:44 status.load -> ../mods-available/status.load

3. 修改 docker-compose.yaml 文件、挂载相应文件

  1. 在宿主机上创建相应文件
  • remoteip.load
# cat remoteip.load LoadModule remoteip_module /usr/lib/apache2/modules/mod_remoteip.so
  • remoteip.conf
# remoteip.conf RemoteIPHeader X-Forwarded-For RemoteIPProxiesHeader X-Forwarded-By
  1. 修改 wordpress 服务的相关配置项
version: '3' services: wordpress: image: wordpress restart: always # ports: # - 8090:80 volumes: - ${PWD}/web:/var/www/html:rw # remoteip.load - ./apache/remoteip.load:/etc/apache2/mods-enabled/remoteip.load:ro # remoteip.conf - ./apache/remoteip.conf:/etc/apache2/mods-enabled/remoteip.conf:ro
  1. 重建容器
docker-compose stop docker-compose rm docker-compose up -d
  1. 测试
可以看出文件已经挂载成功
docker exec -it $your_container_name /bin/bash cd /etc/apache2/mods-enabled ls -al total 20 drwxr-xr-x 1 root root 4096 Jul 27 11:24 . drwxr-xr-x 1 root root 4096 Jun 27 23:44 .. lrwxrwxrwx 1 root root 36 Jun 27 23:44 access_compat.load -> ../mods-available/access_compat.load ... lrwxrwxrwx 1 root root 32 Jun 27 23:44 autoindex.conf -> ../mods-available/autoindex.conf lrwxrwxrwx 1 root root 32 Jun 27 23:44 autoindex.load -> ../mods-available/autoindex.load lrwxrwxrwx 1 root root 30 Jun 27 23:44 deflate.conf -> ../mods-available/deflate.conf ... -rwxrwxrwx 1 root root 69 Jul 27 11:16 remoteip.conf # 这里 -rwxrwxrwx 1 root root 68 Jul 27 11:14 remoteip.load # 这里 lrwxrwxrwx 1 root root 33 Jun 27 23:44 reqtimeout.conf -> ../mods-available/reqtimeout.conf ...
  • 测试正常、收工!
Array ( [HTTP_X_REAL_IP] => 202.***.***.*** [HTTP_X_REAL_PORT] => 10469 [HTTP_X_FORWARDED_PROTO] => http [HTTP_HOST] => expoli.tech [HTTP_X_NGINX_PROXY] => true [HTTP_CONNECTION] => upgrade [HTTP_PRAGMA] => no-cache [HTTP_CACHE_CONTROL] => no-cache [HTTP_UPGRADE_INSECURE_REQUESTS] => 1 [HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 [HTTP_DNT] => 1 ... [SERVER_SOFTWARE] => Apache/2.4.25 (Debian) [SERVER_NAME] => expoli.tech [SERVER_ADDR] => 172.20.0.3 [SERVER_PORT] => 80 [REMOTE_ADDR] => 202.***.***.*** // 成功获取到真实IP [DOCUMENT_ROOT] => /var/www/html [REQUEST_SCHEME] => http [CONTEXT_PREFIX] => [CONTEXT_DOCUMENT_ROOT] => /var/www/html [SERVER_ADMIN] => webmaster@localhost [SCRIPT_FILENAME] => /var/www/html/info.php [REMOTE_PORT] => 40286 [GATEWAY_INTERFACE] => CGI/1.1 [SERVER_PROTOCOL] => HTTP/1.1 [REQUEST_METHOD] => GET ... }
 
欢迎加入喵星计算机技术研究院,原创技术文章第一时间推送。
notion image
 
nginx 主配置文件 nginx.conf 学习清除 git 身份验证失败的密码缓存

  • Waline
  • Utterance