[Redhat] Linux Kernel Module Disable 방법

 리눅스 커널 모듈의 개념과 확인 방법, 특정 모듈의 영구 비활성화 방법을 단계별로 설명합니다.


리눅스에서 모듈이란 무엇인가?

리눅스에서 모듈(Module)은 커널 기능을 확장하기 위한 독립적인 코드 조각입니다. 필요 시 동적으로 로드되거나 언로드할 수 있어, 시스템 자원을 효율적으로 관리할 수 있습니다. 모듈은 하드웨어 드라이버, 파일 시스템, 네트워크 프로토콜 등 다양한 기능을 커널에 제공하는 역할을 합니다.


환경

Red Hat Enterprise Linux 7

Red Hat Enterprise Linux 8

Red Hat Enterprise Linux 9


모듈 확인

lsmod 명령을 통해 활성화되어 있는 모듈을 확인할 수 있습니다.

[root@client ~]# lsmod | more
Module                  Size  Used by
uinput                 20480  1
bridge                290816  0
stp                    16384  1 bridge
llc                    16384  2 bridge,stp
...

이러한 모듈들은 커널에 포함되어 있거나 RPM 패키지에 포함되어 설치됩니다. 각 모듈 정보를 자세히 살펴보면 어디서 설치되었는지 확인이 가능합니다. 모듈의 자세한 정보를 확인하는 방법은 modinfo 명령어를 이용해 가능합니다. 이를 통해 해당 모듈의 경로, 작성자, 라이선스, 의존성, 서명 등 다양한 정보를 확인할 수 있습니다.

# modinfo nf_tables
filename:       /lib/modules/4.18.0-477.10.1.el8_8.x86_64/kernel/net/netfilter/nf_tables.ko.xz
alias:          nfnetlink-subsys-10
author:         Patrick McHardy <kaber@trash.net>
license:        GPL
rhelversion:    8.8
srcversion:     0FAF36C0522959068786F05
depends:        nfnetlink,libcrc32c
intree:         Y
name:           nf_tables
vermagic:       4.18.0-477.10.1.el8_8.x86_64 SMP mod_unload modversions
sig_id:         PKCS#7
signer:         Red Hat Enterprise Linux kernel signing key
sig_key:        55:5D:43:0E:C3:1B:BB:BF:F9:F2:A1:98:F1:E9:3C:1B:F5:64:44:FE
sig_hashalgo:   sha256
signature:      07:9E:AE:86:1F:0A:6C:D9:6C:9A:25:5F:AA:AE:B9:F8:43:58:0E:A2:
                EE:7C:D3:54:89:D1:A8:49:82:D9:B2:07:E1:2B:44:6E:B1:D2:B1:08:
                68:FF:1F:80:84:63:A8:2B:D5:DE:BF:5A:13:70:C3:02:30:53:E4:D8:
                0D:80:B2:DB:A2:FC:1D:FE:41:D5:C6:69:5C:E7:2A:2F:E4:D9:57:57:
                26:B0:03:AE:38:77:83:07:E5:E2:B7:E0:81:47:86:68:28:1F:60:E1:
                90:15:DF:81:A1:4C:B9:D1:9A:E4:3F:69:5F:4A:36:5C:C0:93:16:11:
                CA:4D:DE:7A:4B:07:92:7C:5A:A3:64:A1:86:58:29:CF:86:F8:E7:19:
                23:61:57:81:64:2C:50:F0:10:73:86:0B:15:43:A9:92:33:2A:B7:EE:
                95:FA:5B:D7:5F:F0:F2:74:71:A5:4D:99:D7:E3:5F:28:19:9F:4F:9C:
                94:A2:CF:FF:A2:82:18:CD:4B:FC:14:B4:0D:8A:E1:1A:E6:E7:AD:BC:
                93:9F:6D:B5:8A:94:39:E9:5F:EC:11:2A:29:A9:64:ED:35:CD:33:72:
                FF:4D:E2:13:0C:88:6B:1D:12:49:8E:60:14:64:D2:89:AC:98:9A:C0:
                A9:F3:A5:8F:15:8E:FA:14:D7:5B:FB:99:C1:61:A8:AF:C6:F4:A4:9C:
                D1:1B:A6:37:0C:B2:82:14:C4:54:EF:B4:71:4C:35:78:EA:D3:93:7D:
                2E:19:C9:F7:63:D0:19:A0:D7:08:E0:D3:BC:74:03:CB:F6:BD:46:C0:
                05:41:61:5C:54:C8:46:F4:2E:B7:10:C3:C3:F9:1D:A2:79:5F:52:C0:
                DD:24:97:FA:90:D6:D3:70:C0:6C:29:0D:48:1B:CC:CD:15:C0:92:C6:
                04:64:6C:25:A6:7D:39:22:DD:76:DE:6F:DF:40:39:E3:04:86:BA:29:
                CE:F7:53:89:7C:79:0B:B6:8C:C2:1F:BB:69:2A:58:63:19:0B:48:58:

출력 결과에서 모듈의 파일 경로(/lib/modules/...)를 통해 이 모듈이 OS 커널에 포함되어 배포된 것임을 알 수 있습니다.


영구적으로 모듈이 로드되지 못하도록 설정

시스템 부팅 시 특정 커널 모듈이 자동으로 로드되지 않도록 하려면 /etc/modprobe.d/ 디렉터리에 설정 파일을 생성해야 합니다. 아래와 같이 설정할 수 있습니다.

# echo "blacklist <module-name>" >> /etc/modprobe.d/denylist.conf
# echo "install <module-name> /bin/false" >> /etc/modprobe.d/denylist.conf
  • blacklist: 부팅 시 해당 모듈의 자동 로드를 방지합니다.

  • install ... /bin/false: 해당 모듈을 로드하려 할 때 /bin/false가 실행되어 실패하며, 명시적인 오류 메시지를 출력합니다.

    반면, /bin/true를 지정하면 마찬가지로 로드는 차단되지만, 성공한 것처럼 동작하므로 오류 메시지는 출력되지 않습니다.

파일 이름은 자유롭게 지정할 수 있지만 .conf 확장자를 반드시 포함해야 하며, /etc/modprobe.d/ 디렉터리에 위치해야 합니다.

“blacklist <모듈명>”을 입력하면 부팅 중 모듈이 로드 되는 것을 방지하지만 완벽히 막지는 못합니다. 의존성 걸린 모듈이 실행되거나 modprobe로 실행한 경우 로드될 수 있습니다. 따라서 “install <모듈명> /bin/false”까지 함께 사용하여 모듈이 로드 되려고 할 때 항상 실패하도록 설정할 수 있습니다.


비활성화 예시: nf_tables 모듈

다음은 방화벽에서 사용되는 nf_tables 모듈을 비활성화하는 예시입니다. 먼저 모듈과 방화벽 상태를 확인합니다

# lsmod | grep nf_tables
nf_tables             278528  229 nft_ct,nft_reject_inet,nft_fib_ipv6,nft_fib_ipv4,nft_chain_nat,nft_reject,nft_fib,nft_fib_inet
...

# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
     Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; preset: enabled)
     Active: active (running) since Tue 2024-05-21 13:10:34 KST; 1 day 21h ago
       Docs: man:firewalld(1)
   Main PID: 946 (firewalld)
      Tasks: 2 (limit: 100340)
     Memory: 45.0M
        CPU: 716ms
     CGroup: /system.slice/firewalld.service
             └─946 /usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid

정상적으로 로드되어 있으며 방화벽도 실행 중인 상태입니다.

1. 모듈 비활성화

앞서 설명한 방식대로 nf_tables 모듈의 자동 로드를 방지하도록 설정합니다. 두 가지 방법을 함께 사용해야 완전한 차단이 가능합니다:

# echo "blacklist nf_tables " >> /etc/modprobe.d/denylist.conf
# echo "install nf_tables /bin/false" >> /etc/modprobe.d/denylist.conf

# reboot
이 설정은 모듈이 의존성에 의해 자동 로드되거나 사용자가 modprobe 명령으로 수동 로드를 시도하는 경우를 모두 차단합니다.
참고로 /bin/true를 사용할 수도 있는데, 이 경우에도 모듈 로드는 차단되지만 오류 메시지는 출력되지 않습니다.

2. initramfs 재 생성

/etc/modprobe.d/의 설정이 적용되었더라도, initramfs 이미지에 해당 모듈이 포함되어 있다면 부팅 시 여전히 로드될 수 있습니다. 만약 1번 설정만 적용했는데도 재부팅 후 모듈이 여전히 활성화되어 있다면, 이 단계를 수행해야 합니다.

# cp /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).img.bak

# dracut -f -v
dracut 명령은 새 initramfs를 생성하며, /etc/modprobe.d/ 디렉터리 내 .conf 설정 파일이 자동으로 반영됩니다.

3. 재부팅

initramfs가 갱신된 후에는 시스템을 재부팅해야 설정이 완전히 적용됩니다. 특히, 이미 로드되어 사용 중인 모듈은 단순히 rmmod로 제거할 수 없기 때문에 재부팅을 통해 커널 초기화 과정에서 로드를 차단해야 합니다.

# reboot

4. 적용 확인

재부팅 후 설정이 제대로 적용되었는지 확인합니다. lsmod 명령으로 모듈이 로드되지 않았는지, 그리고 해당 모듈을 사용하는 서비스(firewalld 등)가 중단되었는지 함께 점검합니다.

# lsmod | grep nf_tables
#
# systemctl status firewalld
○ firewalld.service - firewalld - dynamic firewall daemon
     Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; preset: enabled)
     Active: inactive (dead) since Thu 2024-05-23 10:55:39 KST; 12s ago
   Duration: 1.951s
       Docs: man:firewalld(1)
    Process: 932 ExecStart=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS (code=exited, status=0/SUCCESS)
   Main PID: 932 (code=exited, status=0/SUCCESS)
        CPU: 967ms

May 23 10:55:38 rhel92 firewalld[932]: ERROR: 'python-nftables' failed:
                                       JSON blob:
                                       {"nftables": [{"metainfo": {"json_schema_version": 1}}, {"add": {"table">
May 23 10:55:38 rhel92 firewalld[932]: ERROR: Failed to load user configuration. Falling back to full stock con>
May 23 10:55:39 rhel92 firewalld[932]: ERROR: 'python-nftables' failed:
                                       JSON blob:
                                       {"nftables": [{"metainfo": {"json_schema_version": 1}}, {"delete": {"tab>
May 23 10:55:39 rhel92 firewalld[932]: ERROR: COMMAND_FAILED: 'python-nftables' failed:
                                       JSON blob:
...

nf_tables 모듈이 로드되지 않았고, 이를 기반으로 동작하는 firewalld 서비스도 에러와 함께 중지된 상태임을 확인할 수 있습니다.


5. 모듈 로드 차단 검증

설정이 정확하게 적용되었는지 확인하려면 수동으로 모듈을 로드 시도해보는 것이 가장 확실합니다. 아래처럼 modprobe 명령을 실행했을 때 오류가 발생하면 차단이 성공한 것입니다

# modprobe nf_tables
modprobe: ERROR: Error running install command '/bin/false' for module nf_tables: retcode 1
modprobe: ERROR: could not insert 'nf_tables': Invalid argument

참고

https://access.redhat.com/solutions/41278#sharedrhel5678and9

댓글

이 블로그의 인기 게시물

[Linux] RHEL Local YUM Repository 구성

[Linux Command] sudo command 설명

[Ansible Modules] Fetch module 설명 및 활용