前言

設定 github repository 的 webhook 時
發現怎麼樣都沒辦法發 request 到 jenkins
永遠顯示 403 Forbidden (沒有存取資源權限)

此時 nginx 對 ip 的阻擋設定是僅允許 github webhook來源的request

allow 192.168.192.0/24;
allow 192.30.252.0/22;
allow 185.199.108.0/22;
allow 140.82.112.0/20;
allow 143.55.64.0/20;
allow 192.168.1.0/24;
deny all;

查了一下 nginx 的 log 發現
只要是區網外的請求都是來自 192.168.1.1

2024/05/26 04:42:23 [error] 18275#18275: *2 access forbidden by rule, client: 192.168.1.1, server: <jenkins dns>, request: "POST /github-webhook/ HTTP/2.0", host: <jenkins dns>

網路架構


在 Server 的網路架構中
是透過實體網路線藉由數據機接入
透過 openwrt 進行連線 PPPoE
在把外網透過虛擬網路導到其他虛擬機
而前面所提及之 192.168.1.1openwrt的gateway

Openwrt

由於外部封包經由 openwrt 轉送至虛擬機
導致 nginx 收到的 ip 都是 openwrt 所代表的 gateway
這些其實是 Openwrt 裡面的 NAT 幫忙處理的

NAT 會幫忙傳送、轉送封包,分為幾大功能

  1. 封包偽裝
    把私有 IP 改成真實 IP,再進行轉送,讓外部網路無法得知私有網路 IP 分配狀況。
  2. 封包過濾
    攔截網路攻擊封包。
  3. 平衡負載
    讓網路流量根據需求分配至不同主機。

Openwrt 中對於 NAT 有以下設定

由於我不希望 IP 被重新改寫
所以 Action 改用 accept
使內部 nginx 收到正確的來源 ip

CloudFlare CDN

改完 Openwrt 後
再回來看 log
已經不是 gateway 的 ip 了

172.71.154.180 - - [26/May/2024:15:26:09 +0800] "GET /webIcon10.svg HTTP/2.0" 404 186 "https://rmama.cc/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"

但看起來還是跟我們實際發出請求的 ip 有差異

這是由於進入我們的伺服器前
會先經過 CloudFlare
幫忙處理網路封包
導致收到的請求是 CloudFlare轉送來的請求
此時,就需要設定 nginx,讓伺服器收到的真正的來源 ip

Nginx

可以根據 CloudFlare所提供的IP Range 拿到我們要轉換位址的 ip range
由於我是希望全部經由 Cloudflare 的都能被轉換成真實 ip
所以把轉換 realIP 設定改在 nginxPath/nginx.conf

        ##
        # CloudFlare IP Settings
        ##
        set_real_ip_from 173.245.48.0/20;
        set_real_ip_from 103.21.244.0/22;
        set_real_ip_from 103.22.200.0/22;
        set_real_ip_from 103.31.4.0/22;
        set_real_ip_from 141.101.64.0/18;
        set_real_ip_from 108.162.192.0/18;
        set_real_ip_from 190.93.240.0/20;
        set_real_ip_from 188.114.96.0/20;
        set_real_ip_from 197.234.240.0/22;
        set_real_ip_from 198.41.128.0/17;
        set_real_ip_from 162.158.0.0/15;
        set_real_ip_from 104.16.0.0/13;
        set_real_ip_from 104.24.0.0/14;
        set_real_ip_from 172.64.0.0/13;
        set_real_ip_from 131.0.72.0/22;
        set_real_ip_from 2400:cb00::/32;
        set_real_ip_from 2606:4700::/32;
        set_real_ip_from 2803:f800::/32;
        set_real_ip_from 2405:b500::/32;
        set_real_ip_from 2405:8100::/32;
        set_real_ip_from 2a06:98c0::/29;
        set_real_ip_from 2c0f:f248::/32;

        real_ip_header CF-Connecting-IP;

改完之後就可以 sudo systemctl restart nginx
此時再回去看 log 就會是正確的來源 ip 了!!