우분투 서버에서 노드(express) 앱을 systemd 서비스로 등록해서 80포트로 직접 서빙하려는데, 서비스 시작하면 바로 죽습니다. journalctl 보니 이거네요.
Error: listen EACCES: permission denied 0.0.0.0:80
at Server.setupListenHandle [as _listen2] (node:net:...)3000포트로 하면 잘 뜹니다. 1024 이하 포트라 권한 문제인 건 알겠는데, User=를 root로 바꾸면 되긴 하더라고요. 근데 앱을 루트로 돌리는 게 영 찜찜해서요. 더 나은 방법이 있을까요?
댓글 2
systemd 유닛 파일 [Service] 섹션에 이 두 줄 넣으세요.
AmbientCapabilities=CAP_NET_BIND_SERVICE
User=nodeapp
CAP_NET_BIND_SERVICE가 딱 '1024 미만 포트에 바인딩 가능' 능력만 주는 캐패빌리티라, 앱은 일반 유저(nodeapp)로 돌면서 80만 열 수 있게 됩니다. 루트 권한 나머지는 안 갖고요. 수정하고 systemctl daemon-reload 후 재시작하면 EACCES 사라져요.
참고로 setcap으로 노드 바이너리 자체에 캐패빌리티 박는 방법도 도는데, 그건 그 노드로 실행되는 모든 스크립트가 그 권한을 갖게 돼서 추천 안 해요. 그리고 실무에선 보통 앱은 그냥 3000에 두고 앞에 nginx를 리버스프록시로 세워서 80/443을 nginx가 받게 합니다. 어차피 TLS 종료나 정적파일 서빙 때문에 nginx 둘 거면 그게 제일 깔끔해요. 지금처럼 앱 단독이면 AmbientCapabilities가 간단합니다.