feat: update Ansible and deploy workflow for IPv4 domain support

This commit is contained in:
NetworkCats
2026-03-11 05:03:43 +08:00
parent 3f11d2161f
commit d7f24cc0ab
6 changed files with 85 additions and 2 deletions
+3
View File
@@ -125,6 +125,9 @@ jobs:
DB_UPDATE_URL: ${{ secrets.DB_UPDATE_URL }}
ORIGIN_CERT: ${{ secrets.ORIGIN_CERT }}
ORIGIN_KEY: ${{ secrets.ORIGIN_KEY }}
IPV4_DOMAIN: ${{ secrets.IPV4_DOMAIN }}
IPV4_ORIGIN_CERT: ${{ secrets.IPV4_ORIGIN_CERT }}
IPV4_ORIGIN_KEY: ${{ secrets.IPV4_ORIGIN_KEY }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
FIRST_DEPLOY: ${{ steps.detect.outputs.first_deploy }}
+3
View File
@@ -10,6 +10,9 @@
db_update_url: "{{ lookup('env', 'DB_UPDATE_URL') }}"
origin_cert: "{{ lookup('env', 'ORIGIN_CERT') }}"
origin_key: "{{ lookup('env', 'ORIGIN_KEY') }}"
ipv4_domain: "{{ lookup('env', 'IPV4_DOMAIN') | default('', true) }}"
ipv4_origin_cert: "{{ lookup('env', 'IPV4_ORIGIN_CERT') | default('', true) }}"
ipv4_origin_key: "{{ lookup('env', 'IPV4_ORIGIN_KEY') | default('', true) }}"
dockerhub_token: "{{ lookup('env', 'DOCKERHUB_TOKEN') }}"
dockerhub_username: "{{ lookup('env', 'DOCKERHUB_USERNAME') }}"
first_deploy: "{{ lookup('env', 'FIRST_DEPLOY') | default('false', true) }}"
+38
View File
@@ -32,6 +32,44 @@
mode: "0644"
notify: Reload haproxy
- name: Create IPv4 domain TLS certificate directory
ansible.builtin.file:
path: /opt/rustyip/haproxy/certs-ipv4
state: directory
owner: root
group: root
mode: "0755"
when: ipv4_domain | length > 0
- name: Deploy IPv4 domain TLS origin certificate
ansible.builtin.copy:
content: "{{ ipv4_origin_cert }}\n{{ ipv4_origin_key }}"
dest: /opt/rustyip/haproxy/certs-ipv4/origin.pem
owner: root
group: root
mode: "0644"
notify: Reload haproxy
when: ipv4_domain | length > 0
- name: Deploy IPv4 domain list for HAProxy
ansible.builtin.copy:
content: "{{ ipv4_domain }}\n"
dest: /opt/rustyip/haproxy/ipv4_domain.lst
owner: root
group: root
mode: "0644"
when: ipv4_domain | length > 0
notify: Reload haproxy
- name: Deploy empty IPv4 domain list when not configured
ansible.builtin.copy:
content: "# IPv4-only domain not configured\n"
dest: /opt/rustyip/haproxy/ipv4_domain.lst
owner: root
group: root
mode: "0644"
when: ipv4_domain | length == 0
- name: Deploy environment file
ansible.builtin.template:
src: env.j2
@@ -7,7 +7,11 @@ services:
- "443:443"
volumes:
- ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
- ./haproxy/ipv4_domain.lst:/usr/local/etc/haproxy/ipv4_domain.lst:ro
- ./haproxy/certs:/etc/haproxy/certs:ro
{% if ipv4_domain %}
- ./haproxy/certs-ipv4:/etc/haproxy/certs-ipv4:ro
{% endif %}
restart: unless-stopped
ulimits:
nofile:
@@ -3,3 +3,6 @@ DB_PATH=/data/Merged-IP.mmdb
DB_UPDATE_URL={{ db_update_url }}
DB_UPDATE_INTERVAL_HOURS=24
SITE_DOMAIN={{ site_domain }}
{% if ipv4_domain %}
IPV4_DOMAIN={{ ipv4_domain }}
{% endif %}
@@ -36,11 +36,25 @@ frontend http_in
# Access to port 80 is restricted to Cloudflare IPs at the firewall level
# All requests reaching HAProxy come from Cloudflare; no additional ACL validation is required.
# HAProxy's own forwardfor is not enabled; real IP is set explicitly below via CF-Connecting-IP
{% if ipv4_domain %}
# Identify IPv4-only domain traffic by Host header
acl is_ipv4_domain hdr(host) -f /usr/local/etc/haproxy/ipv4_domain.lst
{% endif %}
# HAProxy's own forwardfor is not enabled; real IP is set explicitly below via CF-Connecting-IP
{% if ipv4_domain %}
# Main domain: standard headers
http-request set-header X-Forwarded-For %[req.hdr(CF-Connecting-IP)] if !is_ipv4_domain
http-request set-header X-Real-IP %[req.hdr(CF-Connecting-IP)] if !is_ipv4_domain
# IPv4-only domain: separate header to prevent confusion with the main domain
http-request set-header X-IPv4-Client-IP %[req.hdr(CF-Connecting-IP)] if is_ipv4_domain
http-request del-header X-Forwarded-For if is_ipv4_domain
http-request del-header X-Real-IP if is_ipv4_domain
{% else %}
# Overwrite standard headers directly with the real IP forcibly added by Cloudflare
http-request set-header X-Forwarded-For %[req.hdr(CF-Connecting-IP)]
http-request set-header X-Real-IP %[req.hdr(CF-Connecting-IP)]
{% endif %}
# Rate limiting: tiered based on global request rate
# Track per-IP request rate (per minute)
@@ -63,7 +77,11 @@ frontend http_in
default_backend app
frontend https_in
{% if ipv4_domain %}
bind *:443 ssl crt /etc/haproxy/certs/origin.pem crt /etc/haproxy/certs-ipv4/origin.pem alpn h2,http/1.1 strict-sni
{% else %}
bind *:443 ssl crt /etc/haproxy/certs/origin.pem alpn h2,http/1.1 strict-sni
{% endif %}
# Gzip compression
compression algo gzip
@@ -72,11 +90,25 @@ frontend https_in
# Access to port 443 is restricted to Cloudflare IPs at the firewall level
# All requests reaching HAProxy come from Cloudflare; no additional ACL validation is required.
# HAProxy's own forwardfor is not enabled; real IP is set explicitly below via CF-Connecting-IP
{% if ipv4_domain %}
# Identify IPv4-only domain traffic by Host header
acl is_ipv4_domain hdr(host) -f /usr/local/etc/haproxy/ipv4_domain.lst
{% endif %}
# HAProxy's own forwardfor is not enabled; real IP is set explicitly below via CF-Connecting-IP
{% if ipv4_domain %}
# Main domain: standard headers
http-request set-header X-Forwarded-For %[req.hdr(CF-Connecting-IP)] if !is_ipv4_domain
http-request set-header X-Real-IP %[req.hdr(CF-Connecting-IP)] if !is_ipv4_domain
# IPv4-only domain: separate header to prevent confusion with the main domain
http-request set-header X-IPv4-Client-IP %[req.hdr(CF-Connecting-IP)] if is_ipv4_domain
http-request del-header X-Forwarded-For if is_ipv4_domain
http-request del-header X-Real-IP if is_ipv4_domain
{% else %}
# Overwrite standard headers directly with the real IP forcibly added by Cloudflare
http-request set-header X-Forwarded-For %[req.hdr(CF-Connecting-IP)]
http-request set-header X-Real-IP %[req.hdr(CF-Connecting-IP)]
{% endif %}
# Rate limiting uses the shared stick-table from http_in frontend
http-request track-sc0 req.hdr(CF-Connecting-IP) table http_in