적대적 보안 감사에서 확정된 medium 6건 보완 (critical/high 0): - systemd 유닛(양 노드): NoNewPrivileges + ProtectSystem=strict/ ProtectHome=read-only/ProtectKernel*/ProtectControlGroups/RestrictSUIDSGID/ LockPersonality/RestrictRealtime/RestrictAddressFamilies(+AF_NETLINK) 샌드박싱. - harden_pi.sh: SSH 차단을 마지막 단계([6/6])로 재정렬 — 앞 단계 실패 시 set -e 로 SSH 가 살아있는 상태에서 중단(원격 복구 가능). nftables·unattended-upgrades 를 오프라인(debs/ --no-download)으로도 설치 지원(폐쇄망 harden). 미발견 secret 경고. - install.sh(양 노드): config_local.py 설치 즉시 chmod 600 (harden 전 노출창 제거). - vendor.sh(양 노드): .deb 를 파일명이 아닌 dpkg-deb Architecture 필드로 실검사 (arm64/all 만 허용, 그 외 hard-fail). nftables·unattended-upgrades 를 번들에 포함. 검증(3-리뷰어 워크플로)이 잡은 회귀 동반 수정: - [critical] ProtectHome=read-only 가 lgpio 의 작업디렉터리(.lgd-nfy 파이프) 쓰기를 막아 add_event_detect(누수 인터럽트 등록) 실패 → 데몬 크래시루프 → 감지 불능. Environment=LG_WD=/tmp 로 PrivateTmp 쓰기가능 /tmp 이동(누수 노드 한정, SHT30 무관). - [medium] 오프라인 설치에 --no-install-recommends 추가(vendor --no-recommends 정합, 네트워크 폴백 방지) — install.sh x2 + harden_pi.sh. - SupplementaryGroups=video gpio 명시 · nft|head 에 ||true(SIGPIPE 중단 방지) · online harden 분기에 apt-get update. ※ 온디바이스 런타임 테스트 1회 필요(빌드머신 Windows 에선 systemd 실행 불가): 실 Pi 에서 systemctl start 후 add_event_detect 콜백·카메라 촬영·업로드 정상 확인.
74 lines
3.3 KiB
Desktop File
74 lines
3.3 KiB
Desktop File
# =============================================================================
|
|
# /etc/systemd/system/leak-sensor.service
|
|
# Raspberry Pi 4 부팅 시 누수감지 모니터를 자동 실행하는 서비스
|
|
#
|
|
# 설치 방법:
|
|
# sudo cp systemd/leak-sensor.service /etc/systemd/system/
|
|
# sudo systemctl daemon-reload
|
|
# sudo systemctl enable leak-sensor
|
|
# sudo systemctl start leak-sensor
|
|
# sudo systemctl status leak-sensor
|
|
#
|
|
# ※ WorkingDirectory/ExecStart 경로는 실제 배치 경로에 맞게 수정.
|
|
# 아래는 /home/pi/raspberry_pi4 에 배치한 경우 기준.
|
|
# =============================================================================
|
|
|
|
[Unit]
|
|
Description=e-con 5C-08 Leak Sensor Monitor v2 (Pi 4, with Camera)
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=pi
|
|
Group=pi
|
|
# rpi-lgpio 는 /dev/gpiochip0(root:gpio 660) 접근에 gpio 그룹, 카메라는 video 그룹 필요.
|
|
SupplementaryGroups=video gpio
|
|
WorkingDirectory=/home/pi/raspberry_pi4
|
|
ExecStart=/home/pi/raspberry_pi4/venv/bin/python leak_sensor.py
|
|
Restart=always
|
|
RestartSec=10
|
|
StandardOutput=journal
|
|
StandardError=journal
|
|
SyslogIdentifier=leak-sensor
|
|
|
|
# 환경 변수
|
|
Environment=PYTHONUNBUFFERED=1
|
|
# lgpio(rpi-lgpio 백엔드)는 add_event_detect 시 작업디렉터리에 .lgd-nfy 알림 파이프를
|
|
# 만든다. 아래 ProtectHome=read-only 로 /home 이 읽기전용이 되므로, PrivateTmp 의
|
|
# 쓰기가능 /tmp 로 lgpio 작업디렉터리를 옮긴다. (없으면 누수 인터럽트 등록이 실패해
|
|
# 데몬이 크래시루프 → 누수 감지 불능.) LG_WD 는 lg 라이브러리가 읽는 환경변수.
|
|
# ※ 이 하드닝은 chardev 백엔드(python3-rpi-lgpio) 를 가정한다. sysfs 기반
|
|
# python3-rpi.gpio 로 되돌리면 ProtectKernelTunables/ProtectHome 와 충돌하므로
|
|
# 백엔드를 바꾸지 말 것(vendor.sh/install.sh 의 python3-rpi-lgpio 핀 유지).
|
|
Environment=LG_WD=/tmp
|
|
|
|
# 누수 촬영 임시파일을 프로세스 전용 /tmp 로 격리 (공용 /tmp 노출 방지)
|
|
PrivateTmp=true
|
|
|
|
# ── 샌드박싱(하드닝) — 데몬 침해 시 root 승격·파일시스템 오염을 차단 ──────────
|
|
# User=pi 는 NOPASSWD sudo 계정이므로 NoNewPrivileges 로 setuid(sudo) 승격 경로를 막는다.
|
|
NoNewPrivileges=true
|
|
# 루트파일시스템 읽기전용 + /var/log 만 쓰기 허용(로그 로테이션 포함). /tmp 는 PrivateTmp.
|
|
ProtectSystem=strict
|
|
ReadWritePaths=/var/log
|
|
# /home 는 읽기전용(자기 코드/config_local.py 읽기만; 쓰기·타 계정 홈 접근 차단).
|
|
ProtectHome=read-only
|
|
ProtectKernelModules=true
|
|
ProtectKernelTunables=true
|
|
ProtectControlGroups=true
|
|
RestrictSUIDSGID=true
|
|
LockPersonality=true
|
|
RestrictRealtime=true
|
|
# HTTPS(POST)+로컬소켓(DNS/journal)만. 카메라/GPIO 는 /dev char (소켓 아님)라 무관.
|
|
# AF_NETLINK 필수 — glibc getaddrinfo/NSS 가 로컬주소 열거에 netlink 를 쓴다
|
|
# (빼면 DNS 해석이 간헐 실패 → 서버 POST 불가). AF_INET/6=HTTPS, AF_UNIX=DNS·journal.
|
|
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK
|
|
# ※ PrivateDevices 는 쓰지 않는다 — /dev/gpiochip*, 카메라 노드가 숨겨져 동작 불능.
|
|
|
|
# 재시작 상한 (10분 내 5번 실패 시 중단)
|
|
StartLimitBurst=5
|
|
StartLimitInterval=600s
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|