jaredhendrickson13가 등록한 사용자 정의 REST API를 설치해본다.
pfsense의 shell로 접속하여 패키지를 다운받자.
# pkg add https://github.com/jaredhendrickson13/pfsense-api/releases/latest/download/pfSense-2.6-pkg-API.txz && /etc/rc.restart_webgui
pfsense를 웹으로 접속 후 상단의 네비게이션 중 System의 하위 메뉴인 API를 클릭한다.
REST API에 관한 설정을 할 수 있으며,
여기서는 WAN/LAN 상관없이 JWT로 인증을 거치는 API를 사용해볼 것이다.
원하는 설정값을 입력 후 Save 버튼을 클릭한다.
Display Advanced를 클릭하면 Login Protection이 존재하는데
해당 기능이 체크되어 있고, REST API 호출 시 인증에 실패하면 접근에 제한이 생긴다.
해제해주자.
사용법은 Documentation을 클릭하면 사용법이 출력되며
하단에는 API 명세서가 나와있다.
API를 사용하기 위해서는 인증이 필요하다.
curl을 이용하였을 때 -u 옵션은 HTTP Header의 Authorization에 해당한다.
Python 스크립트를 이용하여 JWT를 발급받아본다.
사용자 아이디는 admin이고 비밀번호는 pfsense일때의 과정이다.
import requests
import json
import base64
url = "http://192.168.0.250"
auth = base64.b64encode("admin:pfsense".encode()).decode()
headers = {"Content-Type":"application/json", "Authorization":f"Basic {auth}"}
response = requests.post(url=url + "/api/v1/access_token", headers=headers, verify=False)
json_obj = json.loads(response.text)
jwt = json_obj["data"]["token"]
access token을 받으면 로그인 의외 API에서 사용한다.
방화벽 룰을 REST API를 이용하여 확인해본다.
import requests
import json
import base64
url = "http://192.168.0.250"
auth = base64.b64encode("admin:pfsense".encode()).decode()
headers = {"Content-Type":"application/json", "Authorization":f"Basic {auth}"}
response = requests.post(url=url + "/api/v1/access_token", headers=headers, verify=False)
json_obj = json.loads(response.text)
jwt = json_obj["data"]["token"]
headers = {"Content-Type":"application/json", "Authorization":f"Bearer {jwt}"}
response = requests.get(url=url + "/api/v1/firewall/rule", headers=headers, verify=False)
print(response.text)
방화벽 룰을 추가해본다.
ipprotocol의 inet은 IPv4, inet6는 IPv6이며
apply는 정책을 바로 적용할지 여부이다.
url = "http://192.168.0.250"
auth = base64.b64encode("admin:pfsense".encode()).decode()
headers = {"Content-Type":"application/json", "Authorization":f"Basic {auth}"}
response = requests.post(url=url + "/api/v1/access_token", headers=headers, verify=False)
json_obj = json.loads(response.text)
jwt = json_obj["data"]["token"]
data = { "type": "block", "interface": "lan", "ipprotocol": "inet", "protocol": "tcp", "src": "any", "srcport": "any", "dst": "8.8.8.8", "dstport": "443", "descr": "test description", "apply": True }
response = requests.post(url=url + "/api/v1/firewall/rule", headers=headers, json=data, verify=False)
print(json.dumps(json.loads(response.text), indent=4))
웹에서 검증을 해본다.
easyrule을 사용하여 Command Line Interface를 통해 방화벽 정책을 생성할 수 있다.
easyrule <action> <interface> <parameters>
action에는 pass, block, showblock, unblock을 설정할 수 있다.
pass 정책을 등록해본다. 사용법은 다음과 같다.
easyrule pass <interface> <protocol> <source address> <destination address> [destination port]
# easyrule pass wan tcp 1.1.1.1 2.2.2.2 8080
Successfully added pass rule!
정책이 등록되었는지 웹으로 확인해볼 수 있다.
block 정책을 등록해본다. 사용법은 다음과 같다.
easyrule block <interface> <source address>
# easyrule block wan 1.2.3.4
Host added successfully
정책이 등록되었는지 웹으로 확인해볼 수 있다.
웹으로 해당 정책을 삭제하더라도 시스템상에서는 삭제가 안되는 듯 하다. unblock을 사용해야한다.
easyrule에 의해 등록된 block 정책을 살펴본다. 사용법은 다음과 같다.
easyrule showblock <interface>
# easyrule showblock wan
1.2.3.4/32
easyrule로 등록한 block 정책을 삭제해본다. 사용법은 다음과 같다.
easyrule unblock <interface> <source address>
# easyrule unblock wan 1.2.3.4
Host unblocked successfully