리눅스에서 모듈이란 무엇인가?
리눅스에서 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:
위에서 보이는 nf_tables 모듈의 실제 파일 위치를 보면 /lib/modules/4.18.0-477.10.1.el8_8.x86_64 하위에 있는 걸 볼 수 있습니다. 파일의 위치로 추정해 볼 때 OS의 커널에서 제공되는 모듈임을 알 수 있습니다.
영구적으로 모듈이 로드되지 못하도록 설정
다음은 시스템 부팅 시 특정 커널 모듈이 자동으로 로드 되지 않도록 설정하는 방법입니다.
# echo "blacklist <module-name>" >> /etc/modprobe.d/denylist.conf
# echo "install <module-name> /bin/false" >> /etc/modprobe.d/denylist.conf
여기서 파일 이름은 관련성 있게 자유롭게 지어도 되지만 파일의 확장자가 .conf로 끝나고, 파일이 /etc/modprobe.d/ 디렉터리에 위치해 있어야 한다는 점은 중요합니다.
“blacklist <모듈명>”을 입력하면 부팅 중 모듈이 로드 되는 것을 방지하지만 완벽히 막지는 못합니다. 의존성 걸린 모듈이 실행되거나 modprobe로 실행한 경우 로드될 수 있습니다. 따라서 “install <모듈명> /bin/false”까지 함께 사용하여 모듈이 로드 되려고 할 때 항상 실패하도록 설정할 수 있습니다.
실제로 방화벽 netfilter에서 사용하는 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. 모듈 비활성화
아래의 명령을 입력하여 모듈을 비활성화 후 합니다.
# echo "blacklist nf_tables " >> /etc/modprobe.d/denylist.conf
# echo "install nf_tables /bin/false" >> /etc/modprobe.d/denylist.conf
# reboot
2. initramfs 재 생성
initramfs에 포함된 모듈이 부팅 과정에 로드될 수 있으므로 initramfs 파일을 재 생성 합니다. /etc/modprobe.d/ 디렉터리에 .conf 파일을 생성하면, dracut이 새로운 initramfs를 생성할 때 이 설정을 인식하고 반영합니다. 혹시 모를 상황에 대비해 재 생성 전 백업을 받습니다.
# cp /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).img.bak
# dracut -f -v
3. 재부팅
사용 중인 모듈이므로 재부팅을 통해 완전히 비활성화해줍니다.
# reboot
4. 확인
재부팅 후 상태를 보면 모듈이 정상적으로 올라오지 않았고 방화벽도 에러를 보이고 있습니다.
# 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:
...
임의로 모듈을 올리려고 해도 /bin/false 설정에 막혀 올라오지 못합니다.
# 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