본문 바로가기

OS/Linux

Linux - 일반계정으로 1024이하 포트 사용방법 (setcap / getcap)

728x90

리눅스에서 1024 이하의 포트는 일반적으로 root 권한이 있어야만 사용할 수 있습니다.

하지만 보안 이유로 인해 일반 사용자 계정으로 웹 서버(Apache 또는 Tomcat)를 실행해야 하는 경우가 많습니다.

이때 capabilities 기능을 사용하여 일반 사용자도 root 권한 없이 1024 이하의 포트를 사용할 수 있습니다.


Capabilities란?

root 계정은 모든 권한을 갖고 있지만 일반 사용자 계정에게 root 권한을 부여하지 않으면서 특정 작업을 허용하려면 capabilities 기능을 사용할 수 있습니다. root 권한을 나누어 특정 작업(예: 포트 바인딩)을 수행할 수 있게 해 줍니다.

특히 cap_net_bind_service라는 권한을 사용하면 일반 사용자도 1024 이하의 포트(“privileged ports”)에 소켓을 바인딩할 수 있게 됩니다. 이를 통해 웹 서버를 일반 사용자로 실행하면서도 필요한 포트를 사용할 수 있습니다.

 


설정 없이 일반 계정으로 80 및 443 포트 사용 시 발생하는 오류

만약 cap_net_bind_service 설정 없이 일반 사용자 계정으로 Apache 또는 Tomcat을 80번, 443번 포트에서 실행하려고 하면, 포트를 바인딩할 수 없다는 오류가 발생합니다.

1. Apache 웹 서버 오류 메시지

Apache를 일반 사용자 계정으로 실행하면서 80번 또는 443번 포트를 사용하려 할 때

(13)Permission denied: AH00072: make_sock: could not bind to address [::]:80
(13)Permission denied: AH00072: make_sock: could not bind to address 0.0.0.0:80
no listening sockets available, shutting down
AH00015: Unable to open logs

2. Tomcat 웹 서버 오류 메시지

Tomcat을 일반 사용자 계정으로 실행할 때

SEVERE [main] org.apache.coyote.AbstractProtocol.init Failed to initialize end point associated with ProtocolHandler ["http-nio-80"]
java.net.BindException: Permission denied
    at java.base/sun.nio.ch.Net.bind0(Native Method)
    at java.base/sun.nio.ch.Net.bind(Net.java:555)
    at java.base/sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:227)
    ...

오류 메시지는 서로 다르지만 Permission denied를 통해 권한이 없다는 것을 유추할 수 있습니다.


준비 사항: libcap 설치

setcap 및 getcap 명령어를 사용하기 위해서는 libcap 패키지가 필요합니다.

1. 우분투 / 데비안 계열

우분투와 같은 데비안 계열의 리눅스에서는 libcap2-bin 패키지가 필요합니다.

# sudo apt install libcap2-bin

2. 레드햇 / CentOS 계열

레드햇 계열의 리눅스는 기본적으로 libcap이 설치되어 있을 가능성이 높지만 만약 설치되지 않았다면 설치합니다.

# sudo yum install libcap

Apache를 일반 사용자로 80 및 443 포트에서 실행하기

일반 사용자 계정에서 80번 및 443번 포트를 사용하려면, cap_net_bind_service 권한을 부여해야 합니다.

1. Apache 실행 파일에 cap_net_bind_service 권한 부여

Apache 실행 파일에 CAP_NET_BIND_SERVICE 권한을 부여하여 일반 사용자 계정이 1024 이하의 포트를 사용할 수 있도록 설정합니다.

  • 우분투/데비안 계열: Apache의 실행 파일 경로는 /usr/sbin/apache2 입니다.
# sudo setcap 'cap_net_bine_service=+ep' /usr/sbin/apache2
  • 레드햇/CentOS 계열: Apache의 실행 파일 경로는 /usr/sbin/httpd 입니다.
# sudo setcap 'cap_net_bind_service=+ep' /usr/sbin/httpd

 

2. 설정 확인

권한이 제대로 부여되었는지 확인하려면 getcap 명령어를 사용합니다.

# getcap /usr/sbin/apache2
# getcap /usr/sbin/httpd

Tomcat을 일반 사용자로 80 및 443 포트에서 실행하기

1. Java 실행 파일에 cap_net_bind_service 권한 부여

Tomcat은 Java로 실행되므로, Java 실행 파일에 CAP_NET_BIND_SERVICE 권한을 부여해야 합니다. Java 실행 파일 경로는 설치된 JDK에 따라 다를 수 있습니다.

# sudo setcap 'cap_net_bind_service=+ep' /usr/lib/jvm/java-11-openjdk-amd64/bin/java
또는
# sudo setcap 'cap_net_bind_service=+ep' /home/samso/jdk/bin/java

 

2. 설정 확인

# getcap /usr/lib/jvm/java-11-openjdk-amd64/bin/java
# getcap /home/samso/jdk/bin/java

 

3. 오류 발생 시

/home/samso/jdk/bin/java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory​
일 경우 ld.so.conf.d 에 java 경로 추가해주고 ldconfig 실행
# vi /etc/ld.so.conf.d/java.conf
/home/samso/jdk/jre/lib/  ## 추가 후

# ldconfig 실행

 


설정 제거

설정이 더 이상 필요하지 않다면 setcap -r 명령어로 권한을 제거할 수 있습니다.

# sudo setcap -r /usr/sbin/apache2
# sudo setcap -r /usr/sbin/httpd
# sudo setcap -r /usr/lib/jvm/java-11-openjdk-amd64/bin/java
# sudo setcap -r /home/samso/jdk/bin/java

 

728x90
반응형