리눅스 서버에서는 대부분의 백그라운드 프로그램을 systemd 서비스로 실행합니다. 하지만 서비스를 정상적으로 실행하는 것에만 집중하다 보면, 필요 이상의 권한을 부여하거나 시스템 전체에 접근할 수 있도록 설정하는 경우가 많습니다.
systemd에는 별도의 보안 프로그램을 설치하지 않고도 서비스의 격리 수준을 분석할 수 있는 systemd-analyze security 명령이 있습니다.
이번 글에서는 간단한 Python 웹 서비스를 만든 후 보안 노출도를 측정하고, systemd 하드닝 옵션을 적용해 점수를 개선해 보겠습니다.
테스트 환경
이번 테스트는 다음 환경에서 진행했습니다.

systemd 보안 점수란?
systemd-analyze security는 서비스의 다음 항목들을 검사합니다.
- root 권한으로 실행하는지
- 추가 권한 획득을 차단했는지
- 시스템 파일에 쓰기가 가능한지
- 사용자 홈 디렉터리에 접근할 수 있는지
- 장치 파일과 커널 설정에 접근할 수 있는지
- Linux Capability가 제한돼 있는지
- 사용할 수 있는 시스템 호출과 네트워크 주소 체계가 제한돼 있는지
검사 결과는 0.0부터 10.0까지의 노출도인 Exposure Level로 표시됩니다.
0.0 ← 격리 설정이 강함
10.0 ← 격리 설정이 거의 없음
systemd는 각 검사 항목에 위험도와 가중치를 적용하고 전체 결과를 0.0~10.0으로 정규화합니다. 자세한 계산 방식은 systemd-analyze 매뉴얼에서 확인할 수 있습니다.
1. 테스트용 웹 페이지 생성
먼저 웹 서버가 제공할 디렉터리와 HTML 파일을 생성합니다.
sudo mkdir -p /srv/security-demo
echo '<h1>systemd security hardening test</h1>' \
| sudo tee /srv/security-demo/index.html
생성된 파일을 확인합니다.
cat /srv/security-demo/index.html
결과는 다음과 같습니다.
![]()
2. 테스트용 systemd 서비스 생성
다음 명령으로 서비스 파일을 생성합니다.
sudo nano /etc/systemd/system/security-demo.service
아래 내용을 입력합니다.
[Unit]
Description=systemd Security Demo Web Server
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/python3 -m http.server 8080 --bind 127.0.0.1 --directory /srv/security-demo
Restart=on-failure
[Install]
WantedBy=multi-user.target
systemd 설정을 다시 불러오고 서비스를 실행합니다.
sudo systemctl daemon-reload
sudo systemctl enable --now security-demo.service
서비스 상태를 확인합니다.
systemctl status security-demo.service --no-pager

웹 서버가 정상적으로 동작하는지도 확인합니다.
curl http://127.0.0.1:8080
다음과 같이 작성한 HTML이 출력되면 정상입니다.
<h1>systemd security hardening test</h1>
3. 적용 전 보안 노출도 측정
현재 서비스의 보안 설정을 분석합니다.
systemd-analyze security --no-pager security-demo.service
주요 결과는 다음과 같습니다.
✗ User=/DynamicUser=
Service runs as root user
✗ NoNewPrivileges=
Service processes may acquire new privileges
✗ PrivateDevices=
Service potentially has access to hardware devices
✗ ProtectSystem=
Service has full access to the OS file hierarchy
✗ ProtectHome=
Service has full access to home directories
✗ ProtectKernelTunables=
Service may alter kernel tunables
✗ PrivateTmp=
Service has access to other software's temporary files
→ Overall exposure level for security-demo.service: 9.6 UNSAFE

적용 전 결과: 9.6 UNSAFE
별도로 실행 사용자를 지정하지 않아 서비스가 root 권한으로 실행됩니다. 파일 시스템, 홈 디렉터리, 장치, 커널 설정 및 시스템 호출 등에 대한 제한도 거의 없는 상태입니다.
4. systemd 하드닝 설정 적용
기존 서비스 파일을 직접 수정하는 대신 drop-in 방식으로 보안 설정을 추가하겠습니다.
원본 서비스 파일과 하드닝 설정을 분리할 수 있어 변경 내역을 확인하거나 설정을 되돌리기 쉽습니다.
sudo systemctl edit security-demo.service
편집기가 열리면 다음 내용을 입력합니다.
[Service]
DynamicUser=yes
NoNewPrivileges=yes
PrivateTmp=yes
PrivateDevices=yes
ProtectSystem=strict
ProtectHome=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectKernelLogs=yes
ProtectControlGroups=yes
ProtectClock=yes
ProtectHostname=yes
RestrictSUIDSGID=yes
RestrictNamespaces=yes
RestrictRealtime=yes
RestrictAddressFamilies=AF_INET AF_INET
LockPersonality=yes
MemoryDenyWriteExecute=yes
RemoveIPC=yes
SystemCallArchitectures=native
SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM
CapabilityBoundingSet=
AmbientCapabilities=
UMask=0077
저장하면 다음 경로에 설정이 생성됩니다.
/etc/systemd/system/security-demo.service.d/override.conf
주요 옵션 설명
| 설정 | 역할 |
|---|---|
DynamicUser=yes |
서비스 실행 시 임시 비-root 계정을 생성 |
NoNewPrivileges=yes |
서비스 프로세스의 추가 권한 획득 차단 |
PrivateTmp=yes |
서비스 전용 /tmp, /var/tmp 제공 |
PrivateDevices=yes |
물리 장치와 주요 장치 파일 접근 제한 |
ProtectSystem=strict |
운영체제 파일 시스템을 읽기 전용으로 제공 |
ProtectHome=yes |
/home, /root, /run/user 접근 차단 |
ProtectKernelTunables=yes |
커널 설정 변경 차단 |
ProtectKernelModules=yes |
커널 모듈 접근 및 로드 차단 |
ProtectKernelLogs=yes |
커널 로그 접근 차단 |
ProtectControlGroups=yes |
cgroup 설정 변경 차단 |
RestrictNamespaces=yes |
새로운 네임스페이스 생성 차단 |
RestrictAddressFamilies= |
사용할 수 있는 소켓 주소 체계 제한 |
SystemCallFilter= |
서비스에서 사용할 수 있는 시스템 호출 제한 |
CapabilityBoundingSet= |
모든 Linux Capability 제거 |
UMask=0077 |
생성한 파일을 기본적으로 서비스 사용자만 접근 가능하도록 설정 |
각 옵션의 자세한 설명은 systemd.exec 공식 문서에서 확인할 수 있습니다.
5. 서비스 재시작 및 정상 작동 확인
변경된 설정을 불러오고 서비스를 재시작합니다.
sudo systemctl daemon-reload
sudo systemctl restart security-demo.service
서비스 상태를 확인합니다.
systemctl status security-demo.service --no-pager
웹 서버가 여전히 정상적으로 동작하는지도 확인합니다.
curl http://127.0.0.1:8080
다음 결과가 출력되면 보안 설정을 적용한 후에도 서비스 기능이 정상적으로 유지되는 것입니다.
<h1>systemd security hardening test</h1>

서비스가 실행되지 않는다면 다음 명령으로 로그를 확인합니다.
sudo journalctl -u security-demo.service -n 50 --no-pager
설정 파일 자체는 다음 명령으로 검사할 수 있습니다.
sudo systemd-analyze verify \
/etc/systemd/system/security-demo.service
6. 적용 후 보안 노출도 재측정
동일한 명령을 다시 실행합니다.
systemd-analyze security --no-pager security-demo.service
하드닝 설정이 적용된 항목에는 체크 표시가 나타납니다.
✓ User=/DynamicUser=
Service runs under a transient non-root user identity
✓ NoNewPrivileges=
Service processes cannot acquire new privileges
✓ ProtectSystem=
Service has strict read-only access to the OS file hierarchy
✓ ProtectHome=
Service has no access to home directories
✓ PrivateTmp=
Service has no access to other software's temporary files
✓ ProtectKernelModules=
Service cannot load kernel modules
✓ CapabilityBoundingSet=~CAP_SYS_ADMIN
Service has no administrator privileges
→ Overall exposure level for security-demo.service: 1.6 OK

적용 후 결과: 1.6 OK
서비스 기능은 그대로 유지하면서 root 실행, 파일 시스템 쓰기, 장치 및 커널 접근 등 불필요한 권한을 제한했습니다.
적용 전후 비교
| 구분 | Exposure Level | 평가 |
|---|---|---|
| 하드닝 적용 전 | 9.6 | UNSAFE |
| 하드닝 적용 후 | 1.6 | OK |
| 개선 결과 | 8.0 감소 | 격리 수준 향상 |
기존 서비스의 기능은 유지하면서 노출도를 9.6에서 1.6까지 낮췄습니다.
왜 0.0까지 낮추지 않았을까?
이 서비스는 HTTP 요청을 처리해야 하므로 호스트 네트워크에 접근할 수 있어야 합니다.
PrivateNetwork=yes를 적용하면 서비스가 별도의 네트워크 네임스페이스로 격리됩니다. 이 경우 호스트에서 127.0.0.1:8080으로 웹 서버에 접근할 수 없게 됩니다.
따라서 PrivateNetwork를 적용하지 않고 다음 설정으로 사용할 수 있는 소켓의 종류만 제한했습니다.
RestrictAddressFamilies=AF_INET AF_INET6
주의사항
systemd-analyze security 결과는 취약점 진단 점수나 CVSS 점수가 아닙니다.
이 명령은 다음 항목을 직접 검사하지 않습니다.
- 프로그램 소스 코드의 보안 취약점
- 설치된 패키지의 알려진 취약점
- 계정과 비밀번호 정책
- 방화벽 설정
- AppArmor 또는 SELinux 정책
- TLS 인증서와 암호화 설정
- 애플리케이션 자체의 인증 및 접근통제
점수 해석 시 주의
1.6 OK가 나오더라도 서비스가 완전히 안전하다는 의미는 아닙니다. 반대로 SSH처럼 root 권한과 네트워크 접근이 필요한 서비스는 점수가 높더라도 실제 취약점이 존재한다는 뜻은 아닙니다. 이 점수는 동일한 서비스에서 설정 적용 전후의 격리 수준을 비교하는 용도로 활용하는 것이 적절합니다.
마무리
systemd는 단순히 서비스를 실행하고 관리하는 도구가 아니라 서비스별 권한과 시스템 접근 범위를 제한할 수 있는 다양한 보안 기능을 제공합니다.
※ 진행과정 정리
- 테스트용 웹 서비스 생성
systemd-analyze security를 이용한 노출도 측정- root 실행 및 과도한 시스템 접근 항목 확인
- systemd drop-in 설정으로 하드닝 적용
- 서비스 정상 작동 확인
- 노출도
9.6 UNSAFE에서1.6 OK로 개선
참고 자료





