# v1.3.1: synced to device .56 reality (then at /home/root/NEW_Web_Configurator). # v1.11.1: app install dir moved to /opt/web-configurator (FHS /opt). The # server from /opt/web-configurator/src on port 9090. # v1.11.16: MemoryMax 48M→128M. 48M was tight — support-bundle(io.BytesIO)+UI 동시 # 사용 시 실측 피크 ~40-50MB로 OOM-kill 위험. 128M = 실피크 ~2.5x 여유 + 누수 방지 # 캡 유지(장비 RAM 3.4GB 대비 3.7%). 정적자산 최대 93KB·업로드는 디스크 스트리밍. [Unit] Description=IoT Web Configurator # v1.6.0 C3: wpa_supplicant@wlan0 이후 기동 — watchdog 첫 틱에 /var/run/wpa_supplicant # 제어 소켓이 보이도록 (부팅 순서 race → wpa 쿼리 실패 → production wpa flap 방지) After=network.target wpa_supplicant@wlan0.service Wants=network.target wpa_supplicant@wlan0.service StartLimitIntervalSec=60 StartLimitBurst=5 [Service] Type=simple ExecStart=/usr/bin/python3 /opt/web-configurator/src/server.py WorkingDirectory=/opt/web-configurator/src Restart=always RestartSec=5 Environment=DB_PATH=/home/root/db/dynamic_data.db Environment=LOG_DIR=/opt/log/dpworldapp Environment=PORT=9090 MemoryMax=128M StandardOutput=journal StandardError=journal # v1.4.0: security hardening — minimum-cost OS-level sandboxing NoNewPrivileges=yes ProtectSystem=strict ProtectHome=read-only # v1.6.0: PrivateTmp yes→no (.56 strace 실측). wpa_cli 는 응답 수신용 클라이언트 소켓을 # /tmp/wpa_ctrl_ 에 bind 하는데(컴파일 고정), PrivateTmp 사설 tmpfs 는 호스트의 # wpa_supplicant 에게 보이지 않아 회신 불가 → 영구 무응답. 공유 /tmp 로 전환하고 # ReadWritePaths 에 /tmp 명시 (ProtectSystem=strict 는 /tmp 도 RO 로 만들므로 필요 — # v1.4.6.6 log-download 의 /tmp staging 도 이 라인으로 유지). 보안 트레이드오프: # /tmp symlink 공격면 일부 복원 — 폐쇄 LAN 단일 운영자 장비라 수용 (CHANGELOG 기록). PrivateTmp=no PrivateDevices=yes ReadWritePaths=/home/root/db /opt/log/dpworldapp /opt/web-configurator /opt/fw_staging /opt/fw_upload -/opt/config_backups -/home/root/network /tmp # /var/run 은 /run 의 symlink — namespace 는 실경로 기준이므로 둘 다 지정 (.56 실측) ReadWritePaths=-/var/run/wpa_supplicant -/run/wpa_supplicant ProtectKernelTunables=yes ProtectKernelModules=yes ProtectControlGroups=yes RestrictSUIDSGID=yes LockPersonality=yes [Install] WantedBy=multi-user.target