Skip to content

Commit 2e848b0

Browse files
authored
Add files via upload
1 parent eed5e62 commit 2e848b0

File tree

3 files changed

+199
-3
lines changed

3 files changed

+199
-3
lines changed

Makefile

+5-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ endif
1313

1414
.SUFFIXES: .c .so .xo .o
1515

16-
all: iptablespush.so
16+
all: iptablespush.so ttl_iptables
17+
18+
ttl_iptables: ttl_iptables.c
19+
$(CC) ttl_iptables.c -o $@ -I /usr/local/include/hiredis -lhiredis
1720

1821
.c.xo:
1922
$(CC) -I. $(CFLAGS) $(SHOBJ_CFLAGS) -fPIC -c $< -o $@
@@ -24,4 +27,4 @@ iptablespush.so: iptablespush.xo
2427
$(LD) -o $@ $< $(SHOBJ_LDFLAGS) $(LIBS) -lc
2528

2629
clean:
27-
rm -rf *.xo *.so
30+
rm -rf *.xo *.so ttl_iptables

iptablespush.c

+83-1
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ int ACCEPT_Insert_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, in
155155
close(fd);
156156

157157
RedisModule_StringSet(key, argv[1]);
158+
158159
size_t newlen = RedisModule_ValueLength(key);
159160
RedisModule_CloseKey(key);
160161
RedisModule_ReplyWithLongLong(ctx, newlen);
@@ -186,6 +187,82 @@ int ACCEPT_Delete_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, in
186187
return REDISMODULE_OK;
187188
}
188189

190+
int TTL_ACCEPT_Insert_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
191+
{
192+
if (argc != 3)
193+
return RedisModule_WrongArity(ctx);
194+
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1],
195+
REDISMODULE_READ | REDISMODULE_WRITE);
196+
long long count;
197+
if ((RedisModule_StringToLongLong(argv[2],&count) != REDISMODULE_OK) ||
198+
(count < 0)) {
199+
return RedisModule_ReplyWithError(ctx,"ERR invalid count");
200+
}
201+
pid_t pid;
202+
int fd;
203+
char tmp_buf[4096];
204+
205+
static char check_command[256], insert_command[256];
206+
sprintf(check_command, "iptables -C INPUT -s %s -j ACCEPT",
207+
RedisModule_StringPtrLen(argv[1], NULL));
208+
sprintf(insert_command, "iptables -I INPUT -s %s -j ACCEPT",
209+
RedisModule_StringPtrLen(argv[1], NULL));
210+
printf("%s || %s\n", RedisModule_StringPtrLen(argv[0], NULL),
211+
RedisModule_StringPtrLen(argv[1], NULL));
212+
fd = execute_popen(&pid, check_command);
213+
redis_waitpid(pid);
214+
if (0 < read(fd, tmp_buf, sizeof(tmp_buf) - 1)) {
215+
close(fd);
216+
execute_popen(&pid, insert_command);
217+
redis_waitpid(pid);
218+
}
219+
close(fd);
220+
RedisModule_StringSet(key, argv[1]);
221+
RedisModule_SetExpire(key, count*1000);
222+
size_t newlen = RedisModule_ValueLength(key);
223+
RedisModule_CloseKey(key);
224+
RedisModule_ReplyWithLongLong(ctx, newlen);
225+
return REDISMODULE_OK;
226+
}
227+
228+
int TTL_DROP_Insert_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
229+
{
230+
if (argc != 3)
231+
return RedisModule_WrongArity(ctx);
232+
RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1],
233+
REDISMODULE_READ | REDISMODULE_WRITE);
234+
long long count;
235+
if ((RedisModule_StringToLongLong(argv[2],&count) != REDISMODULE_OK) ||
236+
(count < 0)) {
237+
return RedisModule_ReplyWithError(ctx,"ERR invalid count");
238+
}
239+
pid_t pid;
240+
int fd;
241+
char tmp_buf[4096];
242+
243+
static char check_command[256], insert_command[256];
244+
sprintf(check_command, "iptables -C INPUT -s %s -j DROP",
245+
RedisModule_StringPtrLen(argv[1], NULL));
246+
sprintf(insert_command, "iptables -I INPUT -s %s -j DROP",
247+
RedisModule_StringPtrLen(argv[1], NULL));
248+
printf("%s || %s\n", RedisModule_StringPtrLen(argv[0], NULL),
249+
RedisModule_StringPtrLen(argv[1], NULL));
250+
fd = execute_popen(&pid, check_command);
251+
redis_waitpid(pid);
252+
if (0 < read(fd, tmp_buf, sizeof(tmp_buf) - 1)) {
253+
close(fd);
254+
execute_popen(&pid, insert_command);
255+
redis_waitpid(pid);
256+
}
257+
close(fd);
258+
RedisModule_StringSet(key, argv[1]);
259+
RedisModule_SetExpire(key, count*1000);
260+
size_t newlen = RedisModule_ValueLength(key);
261+
RedisModule_CloseKey(key);
262+
RedisModule_ReplyWithLongLong(ctx, newlen);
263+
return REDISMODULE_OK;
264+
}
265+
189266
/* This function must be present on each Redis module. It is used in order to
190267
* register the commands into the Redis server. */
191268
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
@@ -210,7 +287,12 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
210287
if (RedisModule_CreateCommand(ctx, "accept.delete",
211288
ACCEPT_Delete_RedisCommand, "write deny-oom", 1, 1, 1) == REDISMODULE_ERR)
212289
return REDISMODULE_ERR;
213-
290+
if (RedisModule_CreateCommand(ctx, "ttl.accept.insert",
291+
TTL_ACCEPT_Insert_RedisCommand, "write deny-oom", 1, 1, 1) == REDISMODULE_ERR)
292+
return REDISMODULE_ERR;
293+
if (RedisModule_CreateCommand(ctx, "ttl.drop.insert",
294+
TTL_DROP_Insert_RedisCommand, "write deny-oom", 1, 1, 1) == REDISMODULE_ERR)
295+
return REDISMODULE_ERR;
214296

215297
return REDISMODULE_OK;
216298
}

ttl_iptables.c

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <ctype.h>
4+
#include <string.h>
5+
#include <unistd.h>
6+
#include <signal.h>
7+
#include <sys/types.h>
8+
#include <sys/wait.h>
9+
#include <hiredis.h>
10+
#include <syslog.h>
11+
#include <fcntl.h>
12+
#include <time.h>
13+
14+
int redis_waitpid(pid_t pid) {
15+
int rc, status;
16+
do {
17+
if (-1 == (rc = waitpid(pid, &status, WUNTRACED))) {
18+
goto exit;
19+
}
20+
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
21+
exit:
22+
23+
return rc;
24+
}
25+
26+
int execute_fork() {
27+
fflush(stdout);
28+
fflush(stderr);
29+
return fork();
30+
}
31+
32+
int execute_popen(pid_t *pid, const char *command) {
33+
int fd[2];
34+
35+
if (-1 == pipe(fd))
36+
return -1;
37+
38+
if (-1 == (*pid = execute_fork())) {
39+
close(fd[0]);
40+
close(fd[1]);
41+
return -1;
42+
}
43+
44+
if (0 != *pid) /* parent process */
45+
{
46+
close(fd[1]);
47+
return fd[0];
48+
}
49+
50+
close(fd[0]);
51+
dup2(fd[1], STDOUT_FILENO);
52+
dup2(fd[1], STDERR_FILENO);
53+
close(fd[1]);
54+
if (-1 == setpgid(0, 0)) {
55+
exit(EXIT_SUCCESS);
56+
}
57+
58+
execl("/bin/sh", "sh", "-c", command, NULL);
59+
exit(EXIT_SUCCESS);
60+
}
61+
62+
int main(int argc, char **argv) {
63+
unsigned int j;
64+
redisContext *c;
65+
redisReply *reply;
66+
const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1";
67+
int port = (argc > 2) ? atoi(argv[2]) : 6379;
68+
69+
int logfd;
70+
if ((logfd = open("/var/log/ttl_iptables.log", O_RDWR | O_CREAT | O_APPEND,
71+
S_IRUSR | S_IWUSR)) == -1) {
72+
fprintf(stderr, "can not open file:logfile\n");
73+
}
74+
75+
struct timeval timeout = { 1, 500000 }; // 1.5 seconds
76+
c = redisConnectWithTimeout(hostname, port, timeout);
77+
if (c == NULL || c->err) {
78+
if (c) {
79+
fprintf(stderr, "Redis connection error: %s\n", c->errstr);
80+
redisFree(c);
81+
} else {
82+
fprintf(stderr, "Connection error: can't allocate redis context\n");
83+
}
84+
exit(1);
85+
}
86+
daemon(0, 0);
87+
static char insert_command[256];
88+
static char msg[1024];
89+
pid_t pid;
90+
int fd;
91+
92+
//reply = redisCommand(c,"psubscribe __key*__:*");
93+
reply = redisCommand(c, "psubscribe __key*__:expired");
94+
while (redisGetReply(c, (void *) &reply) == REDIS_OK) {
95+
printf("%s\n", reply->element[3]->str);
96+
sprintf(insert_command, "iptables -D INPUT -s %s -j DROP",
97+
reply->element[3]->str);
98+
time_t t = time(NULL);
99+
struct tm *loc_time = localtime(&t);
100+
sprintf(msg, "pid=%d %d:%d:%d iptables -D INPUT -s %s -j DROP\n",
101+
getpid(), loc_time->tm_hour, loc_time->tm_min, loc_time->tm_sec,
102+
reply->element[3]->str);
103+
write(logfd, msg, strlen(msg));
104+
fd = execute_popen(&pid, insert_command);
105+
close(fd);
106+
freeReplyObject(reply);
107+
}
108+
redisFree(c);
109+
close(logfd);
110+
return 0;
111+
}

0 commit comments

Comments
 (0)