[英]How to get the real client ip by usig nginx in docker
我使用 .NET Core 后端、角度前端和 nginx 作為 docker 網絡中的反向代理。 我從本地瀏覽器或同一局域網中的另一個客戶端調用前端。 因此沒有使用額外的代理。 我現在嘗試確定客戶端的真實 IP 地址。 我得到了幾個未知的 IP 地址,我無法 ping,但不是客戶端之一。
我做錯了什么或者我忘記了什么?
這里是 Startup.cs 的一部分:
virtual public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
...
}
virtual public void Configure(IApplicationBuilder app, IHostEnvironment env)
{
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,
ForwardLimit = null, // null = disable check
RequireHeaderSymmetry = false,
//KnownProxies = { IPAddress.Parse("<IP Adresse 1>")},
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication();
app.UseMvc();
}
這里是 nginx.conf:
worker_processes 1;
error_log /etc/nginx/logs/error.log;
events {
}
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream ${SERVER_NAME} {
server backend_app:4200;
server 127.0.0.1:4200;
}
server {
listen 443 ssl;
server_name ${SERVER_NAME};
keepalive_timeout 70;
ssl_certificate /etc/nginx/certs/cert.crt;
ssl_certificate_key /etc/nginx/certs/cert.key;
ssl_prefer_server_ciphers on;
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
location / {
proxy_pass http://${SERVER_NAME};
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
減少docker-compose:
version: '3.7'
services:
frontproxy:
networks:
frontproxy_default: {}
public_net:
ipv4_address: 192.168.165.137
application_app:
networks:
frontproxy_default: {}
test_network: {}
application_sql:
networks:
- test_network
application_api:
container_name: api
networks:
- test_network
networks:
test_network:
name: test_network
frontproxy_default:
name: frontproxy_default
public_net:
driver: bridge
ipam:
driver: default
config:
- subnet: 192.168.0.0/24
#gateway: 192.168.165.1
如果您想控制 docker 鏡像的 IP 地址,更好的辦法是自己設置整個編排。
Docker-compose yaml 文件為您提供了自己設置 IP 地址的選項。
docker-compose 默認提供網絡並自行分配 IP 地址。 您可以使用自定義網絡覆蓋默認網絡。
新docker-compose.yaml
文件應如下所示:
就我而言,DB 是 mysql 服務器,API 是 .NET Core WebAPI 項目。 WEB1/2 是兩個前端服務器,對我來說又是 .NET Core MVC 項目。
version: '3.3'
services:
moviedb:
image: mysql
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: password@123
MYSQL_DATABASE: moviedb
MYSQL_USER: movieadmin
MYSQL_PASSWORD: password@123
volumes:
- C:\MvcMovie:/var/lib/mysql
- ./MvcMovie/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
networks:
public_net:
ipv4_address: ${MVCMOVIE_DB_1_IP}
movieapi:
build:
context: .
dockerfile: Dockerfile.api
depends_on:
- moviedb
networks:
public_net:
ipv4_address: ${MVCMOVIE_API_1_IP}
movieweb1:
build:
context: .
dockerfile: Dockerfile.web
networks:
public_net:
ipv4_address: ${MVCMOVIE_WEB_1_IP}
movieweb2:
build:
context: .
dockerfile: Dockerfile.web
networks:
public_net:
ipv4_address: ${MVCMOVIE_WEB_2_IP}
haproxy:
image: haproxy
ports:
- 8080:80
expose:
- 80
networks:
public_net:
ipv4_address: ${HA_PROXY_IP}
environment:
- MVCMOVIE_API_1_IP=${MVCMOVIE_API_1_IP}
- MVCMOVIE_WEB_1_IP=${MVCMOVIE_WEB_1_IP}
- MVCMOVIE_WEB_2_IP=${MVCMOVIE_WEB_2_IP}
- MVCMOVIE_EXPOSED_PORT=${MVCMOVIE_EXPOSED_PORT}
volumes:
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
networks:
public_net:
driver: bridge
ipam:
driver: default
config:
- subnet: ${NETWORK_SUBNET}
特別注意縮進。
在 docker-compose.yaml 旁邊添加一個 .env 文件並使用類似的內容,如下所示。 更改名稱和端口以滿足需要。
MVCMOVIE_EXPOSED_PORT=80
MVCMOVIE_DB_1_IP=192.168.0.10
MVCMOVIE_API_1_IP=192.168.0.20
MVCMOVIE_WEB_1_IP=192.168.0.30
MVCMOVIE_WEB_2_IP=192.168.0.31
HA_PROXY_IP=192.168.0.100
NETWORK_SUBNET=192.168.0.0/24
照這樣說。 您永遠不應該針對 IP 地址進行編碼。 如果我是你,我會執行以下操作之一:
祝你好運。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.