An iptables accident caused by a path

Background: It turned out to be just a lie

Feeling: Damn / (root path symbol), wasting my three days!

Features: rookie-level time tug of war

Introduction: I recently made a Linux-based gateway firewall project on embedded devices. Naturally, iptables is essential. However, an error caused by carelessness in the recent test has caused a lot of trouble, in detail. . .

 

Time: 9 27

Keywords: find the problem

Because I haven’t tested the function of iptables before, I just cross-compiled and can run on the board. You can find this command by typing ip + tab, and the + --help option can also print help information, so I thought that there was no Question, just add rules later.

I read the iptables manual before, and it feels very simple, nothing, there are only a few commonly used rules, as for the other complicated, it is not too late to read it. This day finally decided to show off his skills.

Add a rule:

Iptables –t nat –A PREROUTING –p tcp –d 192.168.1.123 –dport 80 –j DNAT –to-destination 192.168.2.123:80

The result suggests-dport is an unkown option

It's strange, how is it possible? I tried this command on the Linux host, no problem, indicating that the dport option is supported. Isn't it helpful? Take a look. Although it is an e-text, it looks a bit unpleasant, but there is no way, who said this thing was developed by a foreigner!

I scanned it briefly and found that there is indeed no description of the option -dport, but this option is used everywhere in the manual examples, and I have also tried it on the host, no problem, I am puzzled. . .

In this case, Google is usually a good choice, so I started looking for it online. However, as that song sang: "I am a little bug, I want to search and search, but I can't search it anyway...".

In this desperate moment, I decided to look at the source code, isn't it open source! Fortunately, I found this passage without going deeper:

/* some explanations (after four different bugs

 * in 3 different releases): If we encounter a

 * parameter, that has not been parsed yet,

 * it's not an option of an explicitly loaded

 * match or a target.  However, we support

 * implicit loading of the protocol match

 * extension.  '-p tcp' means 'l4 proto 6' and

 * at the same time 'load tcp protocol match on

 * demand if we specify --dport'.

 *

 * To make this work, we need to make sure:

 * - the parameter has not been parsed by

 *   a match (m above)

 * - a protocol has been specified

 * - the protocol extension has not been

 *   loaded yet, or is loaded and unused

 *   [think of iptables-restore!]

 * - the protocol extension can be successively

 *   loaded

 */

It probably means that the --dport option is related to the transport layer and its protocol and needs to be loaded with related modules to use it. This is also true, the ip layer does not have a port. In this case, load the relevant modules. The question comes again. Didn’t the rules specify that the protocol is tcp? According to reason, the tcp module should be automatically loaded. Although our government at all levels has a lot of reason, just like the judge in Nanjing said, according to common sense XX It doesn't make sense to do it; however, the program is different, it doesn't have that rich imagination, everything comes according to the predetermined rules, so I honestly added -m tcp and tried again. The result is still not working, and it seems that the problem is no longer here. In this case, then I will try another rule, without you-can't dport work! Humph! Here is a new rule:

Iptables –I INPUT –p icmp –j DROP

Throw all the ICMP messages, this is simple enough! Press Enter, it doesn't seem to work, a new print appears:

Couldn't load target libipt_standard.so:usr/lib/libexec/xtables/libipt_standard.so could not be found or does not exist. From this point of view, the previous rules cannot be identified—dport is because the tcp module was not loaded successfully. In addition, it can be seen from this print that the program went to the path usr/lib/libexec/xxx to find the shared dynamic library. Then check if there is this library in this path and it is over?

I don't know it, I was surprised at a glance, not to mention the library, even the path does not exist. So is there such a library in the file system? Search and see. It turns out that the dynamic library used by iptables is found under /usr/lib. It seems that the path to the inventory is wrong, or the path specified at compile time is wrong. In this case, to solve this problem, either create a corresponding path and copy the library over; or specify a new path for iptables, and let it go down from /usr/lib to find the required library. Here choose the latter to try.

The path for the program to load the library is generally specified by Makefile, and then the final search is completed with environmental variables. Normally, the default prefix of the program loading library is specified in the software Makefile, such as libexec/xtables/ here, which should actually be a suffix relative to the path in the environment variable. So to modify the path to load the dynamic library can be done by modifying the Makefile. And because the Makefile is automatically generated based on the configuration file, this step can be done in the configure process of the software. For iptables, you can specify in configure—with-xtables=usr/lib

Recompile after Clean, and find that the path searched is indeed set in configure, but the dynamic library is still unsuccessful! depressed! Come here today, and fight tomorrow! As often said in Korean dramas, fighting! (Now I find that this word is often said in the game.)

 

Time: 9 28

Keywords: Further discover the problem

In the morning, I tested the last phenomenon of yesterday. The whole process was twists and turns. Several times I found it was working (I was really excited every time), but I don’t know why, after the test, it can’t be used again. The key is Did not find the law. I don't know what operation is affecting the iptables module, or what is wrong? But the error is the same every time, that is, the library or path cannot be found.

X, turned a blind eye to the library that clearly exists!

Could it be that the library name is wrong, because libipt_xx.so can not be found, but libxt_xx.so exists in the actual directory. But then I thought, no, I succeeded in the morning test. Although I have suspected the problem of library names before, but after searching on the Internet, I found that the previous version was libipt_xxx.so, and now the version has become libxt_xxx.so, so I no longer pay attention to this problem. Is it really the reason for the library name?

Whenever there is nowhere to go, I want to look at the code. Whenever I want to look at the code, I give myself a negative reason: there is too much code, and I have never read the iptable code before, so forget it. .

So I searched the Internet and searched a lot. I read some, and some didn't, but most of them were irrelevant.

After some searching, I found nothing. Think about it as an aimless search. Let's rest and look at other things. Change your mind. For example, what new electronic products have been released recently, what Japanese right-wingers still smoke pipes to the Chinese Embassy, ​​what Chang'e-2 is about to launch, what. . . .

I was a little dizzy when I saw it, I wanted to relax, forget it. Since looking at the code is a little scared, and if you have found any results from the Internet search, then read the book. There is a Linux security system analysis at hand, and there is also a chapter on firewalls. Maybe you will find something.

I walked through the horse and looked at the flowers. The whole content is about some analysis of the architecture of netfilter and iptable, but I did not find a few clear pictures, all of which are sticky code, and some comments are better, but it is still annoying to look at, and I am not in the mood. Look carefully. Looking at the time again, I found that it was already off work, so time was wasted. It’s better to eat seriously. According to past experience, there might be the effect of “the crowd is looking for him a thousand times, but the person is in a dimly lit place”: because of sudden inspiration, I think of the cause of the problem.

After eating, listening to songs, the "most beautiful time" in Manjiang still sounds pretty good. Kill one more, hehe, is the legendary Three Kingdoms Kill. Let's have a 3v3, and inevitably scold each other.

After a hearty fight, I found that it was late again, and it was time to go back, but I was a little unwilling to solve the problem. In order to make up for yourself, just take the book back. Maybe you can go through it a little bit before going to bed, or maybe you can find something from it (as for what you want to find, I don’t know. People have no clue. There are always some strange ideas...). So carrying a stupid book, with a good "wish", he went home like this.

 

Time: 9 29

Keywords: problem solving

Then continue yesterday. The main reason for bringing the book back is to comfort my uneasy heart. I passed it again before going to bed, and I almost dreamed it.

Sitting in front of the computer in the morning, thinking about it, since I can't find it online and I have no clue when searching the book, I can only offer a killer trick: just look at the code! However, it takes some courage to make such a decision, roar!

Just look at it when you say it, and use that print as a starting point to see where it came from. Combining the shallow impression obtained from reading the book before and a search on the Internet, I still found the print that made people's heads big:

#ifndef NO_SHARED_LIBS

static void *load_extension(const char *search_path, const char *prefix, const char *name, bool is_target)

{

const char *dir = search_path, *next;

void *ptr = NULL;

struct stat sb;

char path[256];

 

do {

next = strchr(dir, ':');

if (next == NULL)

next = dir + strlen (dir);

snprintf(path, sizeof(path), "%.*s/libxt_%s.so",

         (unsigned int)(next - dir), dir, name);

 

if (dlopen(path, RTLD_NOW) != NULL) {

/* Found library.  If it didn't register itself,

   maybe they specified target as match. */

if (is_target)

ptr = find_target(name, DONT_LOAD);

else

ptr = find_match(name, DONT_LOAD, NULL);

} else if (stat(path, &sb) == 0) {

fprintf(stderr, "%s: %s\n", path, dlerror());

}

if (ptr != NULL)

return ptr;

snprintf(path, sizeof(path), "%.*s/%s%s.so",

         (unsigned int)(next - dir), dir, prefix, name);

if (dlopen(path, RTLD_NOW) != NULL) {

if (is_target)

ptr = find_target(name, DONT_LOAD);

else

ptr = find_match(name, DONT_LOAD, NULL);

} else if (stat(path, &sb) == 0) {

fprintf(stderr, "%s: %s\n", path, dlerror());

}

if (ptr != NULL)

return ptr;

dir = next + 1;

} while (*next != '\0');

 

return NULL;

}

#endif

It's in this function of the xtables.c file. Okay, let's start from here.

Add some printing before and after to see what logic has gone.

From the results, we can be sure that there is no problem with the library name. The basic logic is: the software loads libxt_xxx.so first, and if the loading is unsuccessful or cannot be found, then load libipt_xxx.so, so as to ensure that there will be no problems. Is it in a high version environment or a low version environment. After further tracking, I found that the dynamic library itself did not load successfully, but the library did exist, and the location and name were correct. The cruel reality made me even more depressed. Fortunately, it’s time for dinner. Let’s go eat first.

I don’t pay attention to taste and speed when I eat, so I can go online after eating quickly.

Going online seems to be just a habit. For non-mainstream networms like me, orthodoxy is not interested in it, and it may be clear at a glance: For example, Shaanxi Normal University provides female standing urinals to save water resources. I was really surprised when I saw this information. After reading it carefully, I had to admire the imagination of modern people. The specific details will not be disclosed here, and interested readers can check it online. For another example, because I saw reports about the movie Hawthorn Tree Love before, I knew that this novel was quite popular. Recently I often take time to take a look. Today, I happened to see a sentence from the third child in the 16th verse, which has a particularly profound impact: my father always lamented, saying that Mao Zedong's sentence makes sense: "Victory often comes after a little more persistence." Sometimes, it seems that you have reached a desperate situation, thinking that there is no hope anymore, but if you hold on and hold on again, you will often see the dawn of victory. Well, a very reasonable paragraph, and at the same time determined to try to solve the problem this afternoon.

Okay, back to the topic. The previous tests were all executed after logging in to the system, but after restarting the system, I found a phenomenon, that is, the command execution before logging in was all good, after logging in, it was prompted that the library could not be found, because the environment variables after logging in were different from before. Yes, is it because the environment variables have been modified? When you have an idea, you have to experiment quickly.

After several rounds of testing, it is found that only the root path in the environment variable can have an impact. It does not work to compare and modify other items, but as long as the root path is changed to /, everything is normal.

The initial cause of the problem seems to be found, so excited!

Excited, but the root cause of the problem has not been found yet,

Strike while the iron is hot and trace the essence of the problem. Since the root path is modified, it means that there is no problem with the library itself. The reason should be that the library cannot be found, and because the library is indeed under /usr/lib/, then the most likely reason is that iptables finds the library The path is still wrong, can it not find /usr/lib? While staring at the system to print in a daze, I suddenly felt my eyes lit up: the usr/lib/libipt_xx.so shared library could not be found, not /usr/lib/libipt_xxx.so, I was dizzy, and there was a root path symbol / missing! ! ! Could it be that I used a relative path when specifying the path in configure? Open the configuration file, and it really is! After thinking about it, all the strange problems encountered before have reasonable explanations, including several cases where they can be used. It is a complete coincidence. It must be because of the operation under the root path. This also explains why there is only Occasionally it is okay. I am going to be mad. . .

Calm down, re-modified the configuration, compile and run again, everything is fine!

I wasted so much time because of a mistake in the beginning. . . .

Shouldn't you give yourself a hard hit? Haha, think about it or forget it. Although it was a mistake, I still learned a lot in the process of solving the problem.

I think the problem that the library cannot be found again in the future should be able to locate it quickly. ^_^

Guess you like

Origin blog.csdn.net/wwwyue1985/article/details/112438943