13 Commits
v0.1 ... v0.2

Author SHA1 Message Date
383f7cd2f2 NIC 설정 저장 및 로드 기능 추가, NIC 변경 감지 및 동적 규칙 적용 로직 개선 2025-06-02 21:52:27 +09:00
7839226e72 Implement code changes to enhance functionality and improve performance 2025-06-02 16:51:59 +09:00
0ae3cfb507 Netlink 상수 추가 및 인터페이스 라우팅에 메트릭 지원 추가 2025-05-30 03:00:37 +09:00
1d27875bd9 README.md에 로컬 자동 PBR 시스템 구성 섹션 추가 및 packer-openstack-ubuntu.json 파일 생성 2025-05-28 20:07:36 +09:00
607dac267e Merge branch 'main' of ssh://ssh.dmslab.xyz:12100/dmslab/policy-routing 2025-05-28 15:40:00 +09:00
4be94ade77 .gitlab-ci.yml에 Python 테스트 추가 및 cloud-init 스크립트 생성, policy_routing.py에서 서비스 재시작 명령 추가 2025-05-28 15:38:59 +09:00
77af62ed56 라이센스 추가 2025-05-28 01:50:12 +00:00
2e67e8f777 Merge branch 'set-secret-detection-config-1' into 'main'
`.gitlab-ci.yml`에서 비밀 탐지를 설정하고 이 파일이 없으면 생성합니다.

See merge request dmslab/policy-routing!3
2025-05-28 01:47:27 +00:00
c8b62a71e1 .gitlab-ci.yml에서 비밀 탐지를 설정하고 이 파일이 없으면 생성합니다. 2025-05-28 01:47:19 +00:00
38e473e336 Merge branch 'set-sast-iac-config-1' into 'main'
`.gitlab-ci.yml`에 SAST IaC를 구성하고 이 파일이 없으면 생성합니다.

See merge request dmslab/policy-routing!2
2025-05-28 01:46:52 +00:00
16a19e8da9 .gitlab-ci.yml에 SAST IaC를 구성하고 이 파일이 없으면 생성합니다. 2025-05-28 01:46:43 +00:00
3bc1a9cf33 Merge branch 'set-sast-config-1' into 'main'
`.gitlab-ci.yml`에 SAST를 구성하고, 아직 존재하지 않는 경우 이 파일을 생성합니다.

See merge request dmslab/policy-routing!1
2025-05-28 01:46:34 +00:00
1da112f914 .gitlab-ci.yml에 SAST를 구성하고, 아직 존재하지 않는 경우 이 파일을 생성합니다. 2025-05-28 01:46:18 +00:00
7 changed files with 939 additions and 858 deletions

33
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,33 @@
# You can override the included template(s) by including variable overrides
# SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
# Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/pipeline/#customization
# Dependency Scanning customization: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings
# Container Scanning customization: https://docs.gitlab.com/ee/user/application_security/container_scanning/#customizing-the-container-scanning-settings
# Note that environment variables can be set in several places
# See https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence
stages:
- build
- test
- deploy
- review
- dast
- staging
- canary
- production
- incremental rollout 10%
- incremental rollout 25%
- incremental rollout 50%
- incremental rollout 100%
- performance
- cleanup
sast:
stage: test
include:
- template: Auto-DevOps.gitlab-ci.yml
python_tests:
stage: test
image: python:3.9-slim-buster
script:
- pip install pytest
- pytest test_policy_routing.py

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 봉정근
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

42
README.md Normal file
View File

@@ -0,0 +1,42 @@
# Policy Routing
이 프로젝트는 정책 기반 라우팅을 구현하기 위한 Python 스크립트입니다. 이 스크립트는 특정 IP 주소에 대해 지정된 게이트웨이를 사용하여 패킷을 라우팅합니다.
사전 조건으로는 `iproute2` 패키지가 설치되어 있어야 하며, 이 패키지는 Linux 시스템에서 네트워크 인터페이스와 라우팅 테이블을 관리하는 데 사용됩니다.
NIC 의 ip 설정이 미리 되어 있어야 합니다.
## 기능
- 특정 IP 주소에 대해 지정된 게이트웨이를 사용하여 패킷 라우팅
- 라우팅 테이블을 생성하고, 해당 테이블에 규칙을 추가하여 정책 기반 라우팅을 구현
- 자동으로 NIC를 검색하고, 해당 NIC에 대한 라우팅 테이블을 설정
# 사용 방법
## 로컬에 자동 PBR 시스템 구성
스크립트는 아래 명령어로 다운로드 받을 수 있습니다
```bash
wget -O policy_routing.py https://git.dmslab.xyz/dmslab/policy-routing/-/raw/main/policy_routing.py
# or
curl -o policy_routing.py https://git.dmslab.xyz/dmslab/policy-routing/-/raw/main/policy_routing.py
```
다운로드한 스크립트를 install 옵션으로 시스템 데몬으로 설치할 수 있습니다
```bash
sudo python3 policy_routing.py install
```
실제 인터페이스가 감지되고 수행이 되었는지 체크할 수 있습니다.
```bash
sudo python3 policy_routing.py status
```
ip rule 을 확인하여 정책 기반 라우팅이 설정되었는지 확인할 수 있습니다.
```bash
ip rule ls
```

View File

@@ -0,0 +1,65 @@
{
"variables": {
"openstack_auth_url": "{{env `OS_AUTH_URL`}}",
"openstack_username": "{{env `OS_USERNAME`}}",
"openstack_password": "{{env `OS_PASSWORD`}}",
"openstack_tenant_name": "{{env `OS_TENANT_NAME`}}",
"openstack_domain_name": "{{env `OS_USER_DOMAIN_NAME`}}",
"openstack_region": "{{env `OS_REGION_NAME`}}",
"source_image_id": "{{env `OS_SOURCE_IMAGE_ID`}}",
"flavor_name": "cpu.2c_2g",
"network_name": "{{env `OS_NETWORK_NAME`}}",
"image_name": "ubuntu 22.04-{{timestamp}} server",
"floating_ip_pool": "{{env `OS_FLOATING_IP_POOL`}}",
"ssh_username": "ubuntu"
},
"builders": [
{
"type": "openstack",
"identity_endpoint": "{{user `openstack_auth_url`}}",
"username": "{{user `openstack_username`}}",
"password": "{{user `openstack_password`}}",
"tenant_name": "{{user `openstack_tenant_name`}}",
"domain_name": "{{user `openstack_domain_name`}}",
"region": "{{user `openstack_region`}}",
"image_name": "{{user `image_name`}}",
"source_image": "{{user `source_image_id`}}",
"flavor": "{{user `flavor_name`}}",
"networks": [
"{{user `network_name`}}"
],
"ssh_username": "{{user `ssh_username`}}",
"security_groups": [
"default"
],
"floating_ip_pool": "private_provider",
"use_floating_ip": true,
"ssh_timeout": "10m",
"image_disk_format": "raw",
"use_blockstorage_volume": true
}
],
"provisioners": [
{
"type": "shell",
"inline": [
"sudo apt-get update",
"sudo apt-get upgrade -y",
"sudo apt-get autoremove -y",
"echo 'Initial system updates and cleanup complete.'"
]
},
{
"type": "file",
"source": "pbr-script-cloud-init.yaml",
"destination": "/tmp/pbr-script-cloud-init.yaml"
},
{
"type": "shell",
"inline": [
"sudo mv /tmp/pbr-script-cloud-init.yaml /etc/cloud/cloud.cfg.d/99-custom-pbr-script.cfg",
"echo 'Cloud-init configuration moved to /etc/cloud/cloud.cfg.d/'"
]
}
]
}

View File

@@ -0,0 +1,45 @@
#cloud-config
write_files:
- path: /tmp/pbr-script-cloud-init.sh
permissions: '0755'
owner: root:root
content: |
#!/bin/bash
# GitLab 스크립트 URL (공개 저장소 또는 접근 가능한 URL)
# 예시: GitLab Pages, Raw 파일 URL 등
# private repository인 경우 인증 관련 부분을 추가해야 합니다. (아래 설명)
SCRIPT_URL="https://git.dmslab.xyz/dmslab/policy-routing/-/raw/main/policy_routing.py"
DEST_PATH="/opt/PBR/routing.py"
# 스크립트 저장될 디렉토리 생성 (필요하다면)
mkdir -p $(dirname "${DEST_PATH}")
echo "Downloading script from ${SCRIPT_URL}..."
# wget 또는 curl 사용
# wget이 일반적으로 더 많이 사용됨
if command -v wget &> /dev/null
then
wget -O "${DEST_PATH}" "${SCRIPT_URL}"
elif command -v curl &> /dev/null
then
curl -o "${DEST_PATH}" "${SCRIPT_URL}"
else
echo "Error: Neither wget nor curl found. Cannot download script."
exit 1
fi
if [ $? -eq 0 ]; then
echo "Script downloaded successfully to ${DEST_PATH}. Executing..."
chmod +x "${DEST_PATH}" # 실행 권한 부여
"${DEST_PATH}" install # 스크립트 실행
else
echo "Error: Failed to download script from ${SCRIPT_URL}."
exit 1
fi
echo "Script execution finished."
runcmd:
- /tmp/pbr-script-cloud-init.sh

File diff suppressed because it is too large Load Diff

View File

@@ -206,6 +206,7 @@ class TestPolicyRoutingManager(unittest.TestCase):
}
table_id = 101
priority = 30100
metric = 1000 # Add metric for testing
# run_command의 side_effect를 설정하여 각 호출에 대한 응답을 시뮬레이션
# 순서대로 호출될 명령에 대한 응답을 정의
@@ -213,14 +214,14 @@ class TestPolicyRoutingManager(unittest.TestCase):
(True, ""), # 1. ip rule del from 192.168.1.10/32
(True, ""), # 2. ip route show table 101 (empty, so flush is skipped)
(True, ""), # 3. ip route add network
(True, ""), # 4. ip route add default
(True, ""), # 4. ip route add default (with metric)
(True, ""), # 5. ip rule add from
(True, ""), # 6. ip rule add iif
(True, "30100: from 192.168.1.10 lookup 101"), # 7. ip rule show (verification)
(True, "default via 192.168.1.1 dev eth0 table 101") # 8. ip route show table 101 (verification)
(True, "default via 192.168.1.1 dev eth0 table 101 metric 1000") # 8. ip route show table 101 (verification)
]
success = self.manager.apply_interface_routing(interface_info, table_id, priority)
success = self.manager.apply_interface_routing(interface_info, table_id, priority, metric)
self.assertTrue(success)
self.manager.logger.error.assert_not_called()
@@ -231,7 +232,7 @@ class TestPolicyRoutingManager(unittest.TestCase):
mock.call(['ip', 'rule', 'del', 'from', '192.168.1.10/32'], ignore_errors=['No such file or directory']), # This is the second call
# mock.call(['ip', 'route', 'flush', 'table', '101'], ignore_errors=['No such file or directory']), # Removed, as table is empty
mock.call(['ip', 'route', 'add', '192.168.1.0/24', 'dev', 'eth0', 'src', '192.168.1.10', 'table', '101'], ignore_errors=['File exists']),
mock.call(['ip', 'route', 'add', 'default', 'via', '192.168.1.1', 'dev', 'eth0', 'table', '101'], ignore_errors=['File exists']),
mock.call(['ip', 'route', 'add', 'default', 'via', '192.168.1.1', 'dev', 'eth0', 'table', '101', 'metric', '1000'], ignore_errors=['File exists']),
mock.call(['ip', 'rule', 'add', 'from', '192.168.1.10/32', 'table', '101', 'pref', '30100'], ignore_errors=['File exists']),
mock.call(['ip', 'rule', 'add', 'iif', 'eth0', 'table', '101', 'pref', '30101'], ignore_errors=['File exists']),
mock.call(['ip', 'rule', 'show']),