Uvicorn_server에서 IP 주소 범위(CIDR 표기법)로 접근을 차단하고 싶습니다.

매출이 오르면 내리는 수수료! 지금 수수료센터에서 전자결제(PG)수수료 비교견적 신청해 보세요!
Uvicorn_server에서 IP 주소 범위(CIDR 표기법)로 접근을 차단하고 싶습니다.

QA

Uvicorn_server에서 IP 주소 범위(CIDR 표기법)로 접근을 차단하고 싶습니다.

본문

  Localhost에 아파치(2.4.52)와 그누보드6(6.0.4)실서비스를 이용하고 있습니다.

 

아파치(httpd.conf)에서는 디렉터리별로 특정 IP_대역(CIDR 표기법)을 차단하고 있습니다.

 

Uvicorn에서는 FastAPI 미들웨어로 차단해야 한다는 조언(이전 질문의 답글)에 따라,

 

/core/middleware.py


"""애플리케이션에 사용되는 미들웨어를 정의합니다."""
from user_agents import parse
 
from fastapi import FastAPI, Request, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.middleware.sessions import SessionMiddleware
 
from core.plugin import (
    register_plugin_admin_menu, get_plugin_state_change_time,
    read_plugin_state, cache_plugin_state, cache_plugin_menu, register_plugin,
    unregister_plugin, delete_router_by_tagname
)
from core.settings import settings
 
    # glitter
import ipaddress
 
def regist_core_middleware(app: FastAPI) -> None:
    """애플리케이션에 아래 미들웨어를 추가합니다.
 
    미들웨어의 실행 순서는 코드의 역순으로 실행됩니다.
    - main.py의 main_middleware()보다 먼저 실행됩니다.
    """
 
    # 기본으로 실행되는 core 미들웨어를 추가합니다.
    .middleware("http")
.
.
    # glitter 차단할 IP 대역 목록
    blocked_ips = ["47.128.0.0/16", "185.0.0.0/8", "85.0.0.0/8"]
 
    # glitter IP 제한 미들웨어를 FastAPI 애플리케이션에 추가
    app.add_middleware(IPBlockMiddleware, blocked_ips=blocked_ips)
.
.
    # glitter Class_Middleware - start
class IPBlockMiddleware(BaseHTTPMiddleware):
    def __init__(self, app: FastAPI, blocked_ips: str):
        super().__init__(app)
        self.blocked_network = ipaddress.ip_network(blocked_ips)
 
    async def dispatch(self, request: Request, call_next):
        client_ip = ipaddress.ip_address(request.client.host)
        if client_ip in self.blocked_network:
            raise HTTPException(status_code=403, detail="Forbidden: Access is denied by m.Glitter.kr.")
        response = await call_next(request)
        return response
 
    # FastAPI 애플리케이션 인스턴스 생성
    app = FastAPI()
 
    .get("/")
    async def read_root():
        return {"message": "Welcome to the FastAPI application!"}
        # glitter Class_Middleware - end
.
.

클래스_미들웨어(IPBlockMiddleware)를 추가하고 

 

regist_core_middleware 함수안에 

 

app.add_middleware(IPBlockMiddleware, blocked_ips=blocked_ips)를 추가하였으나, ㅠ ㅠ .

 

제가 python 언어를 잘 모르는 지라, IP 접근을 막지 못하고 있습니다.

 

                       = = = 조언 부탁드립니다  = = =

 

-  Localhost 정보는 아래와 같습니다.


root@HumanpcNAS:~# uname && uname -r
Linux
6.1.20-efm-standard
.
root@HumanpcNAS:~# python3 -V
Python 3.9.9
.
root@HumanpcNAS:~# cat requirements.txt
.
fastapi>=0.111.0
.
root@HumanpcNAS:~# httpd -v
Server version: Apache/2.4.52 (Unix)
.

 

 

이 질문에 댓글 쓰기 :

답변 2

 

테스트를 해보니 잘 됩니다.

 

다만, 해당 미들웨어.py 수정 하게 되면, 추후 공식 업데이트 내용을 덮어 씌울 경우 삭제되므로 해당 내용에 참고하시길 바랍니다.

 

middleware.py 파일을 열어주세요

 

4번 라인에



from fastapi import FastAPI, Request 

코드를 다음과 같이 수정 해주세요

from fastapi import FastAPI, Request, HTTPException

 

그리고 8번 라인에 다음을 추가 해주세요



from ipaddress import ip_network, ip_address

 

다음 block_ip 함수를 추가 해주세요 저는 18번 라인에 적용했습니다.



async def block_ip(request: Request):
    client_ip = request.client.host
    blocked_ips = ["127.0.0.11", "203.0.113.0/24"]  # 차단하려는 IP 대역을 여기에 추가

    for blocked_ip in blocked_ips:
        if ip_address(client_ip) in ip_network(blocked_ip):
            raise HTTPException(status_code=403, detail="Forbidden")

 

마지막으로 미들웨어 실행될 때 해당 함수를 호출 해주세요 37번 라인에 추가 해주세요



await block_ip(request)

 

위치가 잘 모르겠다 하시면 아래 스샷 빨간색 부분 참조하시길 바랍니다.

 

978180634_1717545994.7592.png

 

-
-  안녕하세요
-
- 귀중한 시간을 내어주셔서 감사합니다.
-
- 초보의 주먹구구식 질문에 자세한 조견을 주셔서, 맹인이라도 해결할 것 같습니다.
-
- 바로 시도해 보겠습니다.
-
- .  .  .  .  .  .  .  .  . 
.
.
.
- 작성하여주신 함수_미들웨어를 18번 줄에 놓았습니다.


async def block_ip(request: Request):
    client_ip = request.client.host
    blocked_ips = ["211.235.72.125", "47.128.0.0/16", "85.0.0.0/8", "185.0.0.0/8"]  # 차단하려는 IP 대역을 여기에 추가

    for blocked_ip in blocked_ips:
        if ip_address(client_ip) in ip_network(blocked_ip):
            raise HTTPException(status_code=403, detail="Forbidden")

-
-  차단한 "211.235.72.125"가 Uvicorn_server 접속에 HTTP_200_OK를 받습니다. ㅠ ㅠ

root@HumanpcNAS:/mnt/VOL1/apache/_logs# cat m.glitter.kr_access_log.20240605
.
.
211.235.72.125 - - [05/Jun/2024:13:51:00 +0900] "GET / HTTP/1.1" 200 45383
211.235.72.125 - - [05/Jun/2024:13:51:06 +0900] "GET / HTTP/1.1" 200 45383
211.235.72.125 - - [05/Jun/2024:13:51:11 +0900] "GET / HTTP/1.1" 200 45383
211.235.72.125 - - [05/Jun/2024:13:51:52 +0900] "GET / HTTP/1.1" 200 45383
.

-
-  제가 뭘~ 잘못한 것인가요?
-
- 아래의 구글_크롤러가 /bbs/qalist에 접근 못하듯이 접근제한(403)을 당하지 않는군요.

34.64.82.64 - - [05/Jun/2024:13:54:15 +0900] "GET /bbs/qalist HTTP/1.1" 403 4800

-
- ㅠ ㅠ
-

-
- 네 ~~


    # 기본으로 실행되는 core 미들웨어를 추가합니다.
    .middleware("http")
    async def core_middleware(request: Request, call_next):
        await block_ip(request)
        if not await should_run_middleware(request):
            return await call_next(request)

        # 플러그인 설정

    ※ 필자는 다음과 같이 해결하였다.

 

      == main.py 수정 사항 ==

!. ip_address 모듈을 사용하여 Server의 main_middleware에

다음의 소스를 추가하는 방법을 사용하였다.

 

!. 특정 IP_대역(CIDR 표기법)을 차단하여 특정 페이지로 리딜렉션시키는 방법으로

  어떤 소스도 터치하지 못하게 한다.

 

!. main.py에 추가된 소스 -


import httpx
import aiohttp
.
from ipaddress import ip_network, ip_address
.
from fastapi.responses import  PlainTextResponse, StreamingResponse
.
.
.
    # 데이터베이스 설치여부 체크 == 필히, 이 주석 밑에 놓으세요.
    blocked_ip_ranges = ["195.2.67.0/24", "47.128.0.0/16", "85.0.0.0/8", "185.0.0.0/8", "211.235.72.120"]
    current_ip = ip_address(get_client_ip(request))
 
    for ip_range in blocked_ip_ranges:
        if current_ip in ip_network(ip_range):
            return RedirectResponse(url="http://115.23.70.228", status_code=303)

    ☆ 위의 소스 6줄은 main_middleware 바로 위에 놓을 것 -

 

★ return RedirectResponse(url="http://115.23.70.228", status_code=303), = 리다이렉트 소스 활용.

답변을 작성하시기 전에 로그인 해주세요.
전체 121
QA 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT