0 | 2 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,5 @@ |
1 |
+Prevent libvirtd from adding iptables rules by calling /sbin/iptables or |
|
2 |
+/sbin/ip6tables. Let it call "iptables --version" though. |
|
3 |
+Compile with: gcc -shared -ldl -fPIC no-iptables.c -o no-iptables.so |
|
4 |
+If needed, add -DNOIPTABLES_DEBUG |
|
5 |
+Usage: LD_PRELOAD=/path/to/no-iptables.so libvirtd |
0 | 6 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,83 @@ |
1 |
+/* |
|
2 |
+ Prevent libvirtd from adding iptables rules by calling /sbin/iptables or |
|
3 |
+ /sbin/ip6tables. Let it call "iptables --version" though. |
|
4 |
+ Compile with: gcc -shared -ldl -fPIC no-iptables.c -o no-iptables.so |
|
5 |
+ If needed, add -DNOIPTABLES_DEBUG |
|
6 |
+ Usage: LD_PRELOAD=/path/to/no-iptables.so libvirtd |
|
7 |
+ |
|
8 |
+ (c) 2016 - Xavier Guerrin |
|
9 |
+ This program is free software. It comes without any warranty, to |
|
10 |
+ the extent permitted by applicable law. You can redistribute it |
|
11 |
+ and/or modify it under the terms of the Do What The Fuck You Want |
|
12 |
+ To Public License, Version 2, as published by Sam Hocevar. See |
|
13 |
+ http://www.wtfpl.net/ for more details. |
|
14 |
+*/ |
|
15 |
+#define _GNU_SOURCE |
|
16 |
+#include <dlfcn.h> |
|
17 |
+#include <errno.h> |
|
18 |
+#include <stdio.h> |
|
19 |
+#include <string.h> |
|
20 |
+#include <unistd.h> |
|
21 |
+ |
|
22 |
+#ifndef NOIPTABLES_SO_NAME |
|
23 |
+#define NOIPTABLES_SO_NAME "no-iptables.so" |
|
24 |
+#endif |
|
25 |
+ |
|
26 |
+typedef int (*execve_function_type)(const char *, char *const *, char *const *); |
|
27 |
+ |
|
28 |
+/* Pointer to the actual execve symbol. */ |
|
29 |
+execve_function_type actual_execve = NULL; |
|
30 |
+ |
|
31 |
+/* When refusing to run iptables, we simply run "true" instead: */ |
|
32 |
+const char *noexec_filename = "/bin/true"; |
|
33 |
+char *const noexec_argv[] = { "/bin/true", NULL }; |
|
34 |
+char *const noexec_envp[] = { NULL }; |
|
35 |
+ |
|
36 |
+/* |
|
37 |
+ libvirtd is liable to use two functions to execute other programs: |
|
38 |
+ - execv() |
|
39 |
+ - execve() |
|
40 |
+*/ |
|
41 |
+int execv(const char *filename, char *const *argv) { |
|
42 |
+ return execve(filename, argv, __environ); |
|
43 |
+} |
|
44 |
+ |
|
45 |
+int execve(const char *filename, char *const *argv, char *const *envp) { |
|
46 |
+ char *error_string; |
|
47 |
+ |
|
48 |
+ /* Ask the linker to provide us with the actual execve symbol: */ |
|
49 |
+ if (!actual_execve) { |
|
50 |
+ actual_execve = (execve_function_type)dlsym(RTLD_NEXT, "execve"); |
|
51 |
+ if (!actual_execve) { |
|
52 |
+ error_string = dlerror(); |
|
53 |
+ if (error_string) { |
|
54 |
+ dprintf(2, "%s: unable to find the actual execve symbol: %s\n", NOIPTABLES_SO_NAME, error_string); |
|
55 |
+ } |
|
56 |
+ else { |
|
57 |
+ dprintf(2, "%s: unable to find the actual execve symbol\n", NOIPTABLES_SO_NAME); |
|
58 |
+ } |
|
59 |
+ errno = ENOENT; |
|
60 |
+ return -1; |
|
61 |
+ } |
|
62 |
+ } |
|
63 |
+ |
|
64 |
+ /* Determine whether libvirtd is trying to call iptables: */ |
|
65 |
+ if (!strncmp(filename, "/sbin/iptables", 15) || !strncmp(filename, "/sbin/ip6tables", 16)) { |
|
66 |
+#ifdef NOIPTABLES_DEBUG |
|
67 |
+ dprintf(2, "OMG it's calling %s!\n", filename); |
|
68 |
+#endif |
|
69 |
+ /* Do not interfere when libvirtd tries to run iptables --version: */ |
|
70 |
+ if (argv[0] && argv[1] && !strncmp(argv[1], "--version", 10)) { |
|
71 |
+#ifdef NOIPTABLES_DEBUG |
|
72 |
+ dprintf(2, "Oh, it's ok, it's just calling %s --version.\n", filename); |
|
73 |
+#endif |
|
74 |
+ goto let_it_go; |
|
75 |
+ } |
|
76 |
+ /* Refuse to run the program: */ |
|
77 |
+ return actual_execve(noexec_filename, noexec_argv, noexec_envp); |
|
78 |
+ } |
|
79 |
+ |
|
80 |
+ let_it_go: |
|
81 |
+ /* Execute the program pointed to by filename as initially intended: */ |
|
82 |
+ return actual_execve(filename, argv, envp); |
|
83 |
+} |
0 | 84 |
new file mode 100755 |
... | ... |
@@ -0,0 +1,16 @@ |
1 |
+#!/bin/bash |
|
2 |
+export LD_PRELOAD="$(readlink -f no-iptables.so)" |
|
3 |
+ |
|
4 |
+for exe in 'iptables' 'ip6tables'; do |
|
5 |
+ echo "Executing ${exe}" |
|
6 |
+ bash -c "${exe}" |
|
7 |
+ echo "----------------------------------------" |
|
8 |
+ |
|
9 |
+ echo "Executing ${exe} --version" |
|
10 |
+ bash -c "${exe} --version" |
|
11 |
+ echo "----------------------------------------" |
|
12 |
+ |
|
13 |
+ echo "Executing ${exe} -L -n" |
|
14 |
+ bash -c "${exe} -L -n" |
|
15 |
+ echo "----------------------------------------" |
|
16 |
+done |