mirror of
https://github.com/jung-geun/policy-routing.git
synced 2025-12-20 02:34:39 +09:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 383f7cd2f2 | |||
| 7839226e72 | |||
| 0ae3cfb507 | |||
| 1d27875bd9 | |||
| 607dac267e | |||
| 4be94ade77 | |||
| 77af62ed56 | |||
| 2e67e8f777 | |||
| c8b62a71e1 | |||
| 38e473e336 | |||
| 16a19e8da9 | |||
| 3bc1a9cf33 | |||
| 1da112f914 |
33
.gitlab-ci.yml
Normal file
33
.gitlab-ci.yml
Normal 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
21
LICENSE
Normal 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
42
README.md
Normal 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
|
||||
```
|
||||
65
packer-openstack-ubuntu.json
Normal file
65
packer-openstack-ubuntu.json
Normal 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/'"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
45
pbr-script-cloud-init.yaml
Normal file
45
pbr-script-cloud-init.yaml
Normal 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
|
||||
1582
policy_routing.py
1582
policy_routing.py
File diff suppressed because it is too large
Load Diff
@@ -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']),
|
||||
|
||||
Reference in New Issue
Block a user