Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: Build & Test

on:
push:
branches: [main]
tags: ["v*"]
pull_request:
branches: [main]

jobs:
unit-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run unit tests
run: bash tests/test_unit.sh

integration-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install firewalld
run: |
sudo apt-get update
sudo apt-get install -y firewalld python3 curl iproute2

- name: Start firewalld
run: |
sudo systemctl unmask firewalld
sudo systemctl start firewalld
sudo firewall-cmd --state

- name: Run integration tests
run: sudo bash tests/test_integration.sh

build:
runs-on: ubuntu-latest
needs: [unit-test]
strategy:
matrix:
include:
- distro: fedora:latest
name: fedora
- distro: rockylinux:8
name: el8
- distro: rockylinux:9
name: el9
- distro: almalinux:9
name: alma9
container: ${{ matrix.distro }}
steps:
- uses: actions/checkout@v4

- name: Install build dependencies
run: |
dnf install -y rpm-build make systemd-rpm-macros

- name: Build RPM
run: make rpm

- name: Verify RPM
run: |
rpm -qip ~/rpmbuild/RPMS/noarch/firewalld-cloudflare-http-*.rpm
rpm -qlp ~/rpmbuild/RPMS/noarch/firewalld-cloudflare-http-*.rpm

- name: Upload RPM
uses: actions/upload-artifact@v4
with:
name: rpm-${{ matrix.name }}
path: ~/rpmbuild/RPMS/noarch/firewalld-cloudflare-http-*.rpm

- name: Upload SRPM
if: matrix.name == 'fedora'
uses: actions/upload-artifact@v4
with:
name: srpm
path: ~/rpmbuild/SRPMS/firewalld-cloudflare-http-*.src.rpm

release:
needs: [build, integration-test]
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download all RPM artifacts
uses: actions/download-artifact@v4
with:
pattern: rpm-*
path: ./rpms
merge-multiple: true

- name: Download SRPM
uses: actions/download-artifact@v4
with:
name: srpm
path: ./srpms

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
files: |
./rpms/*.rpm
./srpms/*.src.rpm
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.tar.gz
*.rpm
firewalld-cloudflare-http-*/
32 changes: 32 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
NAME := firewalld-cloudflare-http
VERSION := 1.0.0
TARBALL := $(NAME)-$(VERSION).tar.gz

RPMBUILD := $(HOME)/rpmbuild

.PHONY: all srpm rpm tarball clean

all: rpm

tarball:
mkdir -p $(NAME)-$(VERSION)
cp -a src LICENSE $(NAME)-$(VERSION)/
cp $(NAME).spec $(NAME)-$(VERSION)/
tar czf $(TARBALL) $(NAME)-$(VERSION)
rm -rf $(NAME)-$(VERSION)

srpm: tarball
mkdir -p $(RPMBUILD)/{SOURCES,SPECS}
cp $(TARBALL) $(RPMBUILD)/SOURCES/
cp $(NAME).spec $(RPMBUILD)/SPECS/
rpmbuild -bs $(RPMBUILD)/SPECS/$(NAME).spec

rpm: tarball
mkdir -p $(RPMBUILD)/{SOURCES,SPECS}
cp $(TARBALL) $(RPMBUILD)/SOURCES/
cp $(NAME).spec $(RPMBUILD)/SPECS/
rpmbuild -ba $(RPMBUILD)/SPECS/$(NAME).spec

clean:
rm -f $(TARBALL)
rm -rf $(NAME)-$(VERSION)
77 changes: 77 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# firewalld-cloudflare-http

firewalld の ipset + rich rule を使って、HTTP/HTTPS (80/443) を Cloudflare IP からのみ許可する RPM パッケージ。

## インストール

```bash
# RPM をビルドしてインストール
make rpm
sudo dnf install ~/rpmbuild/RPMS/noarch/firewalld-cloudflare-http-*.rpm
```

## 動作

インストール時に以下が自動で行われます:

1. Cloudflare の公開 IP リスト ([IPv4](https://www.cloudflare.com/ips-v4), [IPv6](https://www.cloudflare.com/ips-v6)) を取得
2. firewalld ipset (`cloudflare-ipv4`, `cloudflare-ipv6`) を作成
3. デフォルト zone に HTTP/HTTPS を許可する rich rule を追加
4. 週次の systemd timer で IP リストを自動更新

## インストール後の確認

```bash
# ipset の確認
sudo firewall-cmd --get-ipsets
sudo firewall-cmd --info-ipset=cloudflare-ipv4
sudo firewall-cmd --info-ipset=cloudflare-ipv6

# rich rule の確認
sudo firewall-cmd --list-rich-rules

# timer の確認
systemctl status firewalld-cloudflare-http-update.timer
```

## 既存の HTTP/HTTPS サービスの無効化

Cloudflare IP 以外からの HTTP/HTTPS を拒否するには、zone から `http`/`https` サービスを削除してください:

```bash
sudo firewall-cmd --permanent --remove-service=http
sudo firewall-cmd --permanent --remove-service=https
sudo firewall-cmd --reload
```

## 手動更新

```bash
# IP リストの手動更新
sudo /usr/libexec/firewalld-cloudflare-http/update update

# rich rule の再セットアップ (特定の zone を指定可能)
sudo /usr/libexec/firewalld-cloudflare-http/update setup [zone]
```

## アンインストール

```bash
sudo dnf remove firewalld-cloudflare-http
```

アンインストール時に rich rule と ipset は自動で削除されます。

## ビルド要件

- `rpmbuild` (`rpm-build` パッケージ)
- `make`

```bash
sudo dnf install rpm-build make
make rpm
```

## ライセンス

Apache License 2.0
65 changes: 65 additions & 0 deletions firewalld-cloudflare-http.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
Name: firewalld-cloudflare-http
Version: 1.0.0
Release: 1%{?dist}
Summary: Firewalld rules to allow HTTP/HTTPS only from Cloudflare IPs
License: Apache-2.0
URL: https://github.com/39ff/firewalld-cloudflare-http-rules

Source0: %{name}-%{version}.tar.gz

BuildArch: noarch
BuildRequires: systemd-rpm-macros
Requires: firewalld
Requires: curl
Requires: systemd

%description
Manages firewalld ipsets and rich rules to allow HTTP (port 80) and
HTTPS (port 443) traffic only from Cloudflare IP addresses.

Cloudflare IP ranges are fetched automatically from
https://www.cloudflare.com/ips-v4 and https://www.cloudflare.com/ips-v6
and kept up-to-date via a weekly systemd timer.

%prep
%setup -q

%install
install -Dm 0755 src/firewalld-cloudflare-http-update \
%{buildroot}%{_libexecdir}/firewalld-cloudflare-http/update

install -Dm 0644 src/firewalld-cloudflare-http-update.service \
%{buildroot}%{_unitdir}/firewalld-cloudflare-http-update.service

install -Dm 0644 src/firewalld-cloudflare-http-update.timer \
%{buildroot}%{_unitdir}/firewalld-cloudflare-http-update.timer

%post
%systemd_post firewalld-cloudflare-http-update.timer

if systemctl is-active --quiet firewalld; then
%{_libexecdir}/firewalld-cloudflare-http/update setup || :
fi

systemctl enable --now firewalld-cloudflare-http-update.timer || :

%preun
%systemd_preun firewalld-cloudflare-http-update.timer
%systemd_preun firewalld-cloudflare-http-update.service

if [ "$1" -eq 0 ] && systemctl is-active --quiet firewalld; then
%{_libexecdir}/firewalld-cloudflare-http/update remove || :
fi

%postun
%systemd_postun_with_restart firewalld-cloudflare-http-update.timer

%files
%license LICENSE
%{_libexecdir}/firewalld-cloudflare-http/update
%{_unitdir}/firewalld-cloudflare-http-update.service
%{_unitdir}/firewalld-cloudflare-http-update.timer

%changelog
* Tue Feb 03 2026 39ff - 1.0.0-1
- Initial release
Loading