-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
358 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
* text=auto | ||
*.c text=text | ||
*.h text=text | ||
Makefile text eol=cr |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,9 @@ | ||
# Prerequisites | ||
*.d | ||
.idea | ||
depend | ||
port-open | ||
port-close | ||
|
||
# Object files | ||
*.o | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# Generic MinGW makefile (C source only) | ||
# Modify variables/macros to fit your program | ||
|
||
INSTALL_DIR=/usr/local | ||
SBIN_DIR=$(INSTALL_DIR)/sbin | ||
|
||
# make / make all | will compile your program. | ||
# make clean | deletes all compiled object and executable files. | ||
# make depend | rebuilds the dependancy list | ||
# make run | compiles (if needed) and runs your program | ||
|
||
# Compiler command | ||
CC = gcc | ||
|
||
# Linker command | ||
LD = gcc | ||
|
||
# Flags to pass to the compiler - add "-g" to include debug information | ||
CFLAGS = -Wall | ||
|
||
# Flags to pass to the linker | ||
LDFLAGS = | ||
|
||
# Command used to delete files | ||
RM = rm | ||
|
||
# List your object files here | ||
OBJS = port-open.o | ||
|
||
# List your source files here | ||
SRCS = port-open.c | ||
|
||
# Define your compile target here. | ||
PROG = port-open | ||
|
||
# Compile everything. | ||
all: $(PROG) | ||
|
||
# Link the program | ||
$(PROG): $(OBJS) | ||
$(LD) $(LDFLAGS) $(OBJS) -s -o $(PROG) | ||
|
||
# All .o files depend on their corresponding .c file | ||
%.o: %.c | ||
$(CC) $(CFLAGS) -c $< | ||
|
||
install: | ||
cp -a port-open $(SBIN_DIR)/ | ||
cd $(SBIN_DIR) && ln -fs port-open port-close | ||
|
||
clean: | ||
$(RM) -f $(PROG) | ||
$(RM) -f *.o port-close | ||
|
||
distclean: clean | ||
$(RM) -f depend | ||
|
||
|
||
depend: | ||
$(CC) $(CFLAGS) -MM $(SRCS) > depend | ||
|
||
|
||
include depend |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,52 @@ | ||
# knockd-tools | ||
Tools to use with Judd Vinet's knockd | ||
|
||
## ABOUT | ||
|
||
This set of tools to use with [Judd Vinet's knockd](https://zeroflux.org/projects/knock) port-knocking server/client. | ||
The same functionality can be accomplished with a small script, but port-close which will stay in ram for hours and | ||
maybe days uses very little ram. | ||
|
||
## INSTALL | ||
|
||
To install the tools in /usr/local/sbin run: | ||
|
||
$ make | ||
$ sudo make install | ||
|
||
If you want other directories, edit Makefile and change: | ||
|
||
INSTALL_DIR=/usr/local | ||
SBIN_DIR=$(INSTALL_DIR)/sbin | ||
|
||
Or simply copy port-open to whatever dir you want and make a sym or hard link port-close pointing to port-open | ||
|
||
## EXAMPLE | ||
|
||
First you need to create **iptables** rules: | ||
|
||
iptables -N knock | ||
iptables -I INPUT -j knock | ||
|
||
For example configuration check `knockd-example.conf` | ||
|
||
## TEST | ||
|
||
To test your installation you can run: | ||
|
||
iptables -N knock | ||
port-open 8.8.8.8 80 20 | ||
watch iptables -xvnL knock | ||
|
||
You should see a rule accepting connections from 8.8.8.8 on port 80. After after 20 seconds the rule should disappear. | ||
|
||
|
||
Chain knock (1 references) | ||
pkts bytes target prot opt in out source destination | ||
0 0 ACCEPT tcp -- * * 8.8.8.8 0.0.0.0/0 tcp dpt:80 | ||
|
||
|
||
## LINKS | ||
|
||
* [Judd Vinet's knockd](https://zeroflux.org/projects/knock) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
[options] | ||
logfile = /var/log/knockd.log | ||
Interface = eth1 | ||
# Interface = eth0 | ||
|
||
|
||
[openSSH] | ||
sequence = 1,2,3,4 | ||
seq_timeout = 10 | ||
command = /usr/local/sbin/port-open %IP% 22 18000 | ||
tcpflags = syn | ||
|
||
[openSSH2d] | ||
sequence = 5,6,7,8 | ||
seq_timeout = 10 | ||
# timeout = 3600*24*2 | ||
command = /usr/local/sbin/port-open %IP% 22 172800 | ||
tcpflags = syn | ||
|
||
[closeSSH] | ||
sequence = 4,3,2,1 | ||
seq_timeout = 5 | ||
command = /usr/local/sbin/port-close %IP% 22 | ||
tcpflags = syn | ||
|
||
[beep] | ||
sequence = 2000,3000,4000 | ||
seq_timeout = 10 | ||
command = echo "beep" >> /tmp/beep.log | ||
tcpflags = syn | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
/** | ||
* Compile: | ||
* gcc -s -o port-open port-open.c | ||
* cp -a port-open /usr/local/sbin | ||
* cd /usr/local/sbin | ||
* ln -sf port-open port-close | ||
* | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <string.h> | ||
#include <stdlib.h> | ||
#include <stdbool.h> | ||
#include <libgen.h> | ||
#include <sys/types.h> | ||
#include <unistd.h> | ||
|
||
#define IPTABLES_OPEN_CMD "/sbin/iptables -A knock -s %s -p tcp --dport %d -j ACCEPT >/dev/null" | ||
#define IPTABLES_CLOSE_CMD "/sbin/iptables -D knock -s %s -p tcp --dport %d -j ACCEPT >/dev/null 2>&1" | ||
|
||
#define PROG_PORT_OPEN 1 | ||
#define PROG_PORT_CLOSE 2 | ||
|
||
char *name; | ||
char progPath[1026]; | ||
bool hasDir = false; | ||
int program = 1; | ||
long timeout = 0; | ||
|
||
bool verifyIp(const char *ip); | ||
bool verifyPort(long port); | ||
|
||
void usageOpen(){ | ||
printf("Adds ACCEPT rule for a given IP and port using iptables. If timeout is grater than 0 starts port-close with the same parameters:\n"); | ||
printf("Usage:\n"); | ||
printf(" %s <ip> <port> [timeout=0]\n", name); | ||
} | ||
|
||
void usageClose(){ | ||
printf("Removes the iptables ACCEPT rule, previously added with port-open after timeout seconds.\n"); | ||
printf("Usage:\n"); | ||
printf(" %s <ip> <port> [timeout=0]\n", name); | ||
} | ||
|
||
void usage() { | ||
switch(program){ | ||
case PROG_PORT_OPEN: | ||
usageOpen(); | ||
break; | ||
case PROG_PORT_CLOSE: | ||
usageClose(); | ||
break; | ||
} | ||
} | ||
|
||
int portOpen(int argc, char **argv){ | ||
long tmp; | ||
char **endPtr = NULL; | ||
|
||
if(argc < 3){ | ||
usageOpen(); | ||
return 1; | ||
} | ||
|
||
const char *ip = argv[1]; | ||
if(!verifyIp(ip)) | ||
return 1; | ||
|
||
tmp = strtol(argv[2], endPtr, 10); | ||
const int port = (int) tmp; | ||
if(!verifyPort(port)) | ||
return 1; | ||
|
||
if(argc > 3){ | ||
timeout=strtol(argv[3], endPtr, 10); | ||
} | ||
|
||
char *cmd = malloc(1500); | ||
sprintf(cmd, IPTABLES_OPEN_CMD, ip, (int)port); | ||
// printf("running cmd: %s\n", cmd); | ||
system(cmd); | ||
|
||
if(timeout > 0) { | ||
sprintf(cmd, "%sport-close %s %d %d", progPath, ip, (int)port, (int)timeout); | ||
// printf("port close cmd: %s\n", cmd); | ||
system(cmd); | ||
} | ||
free(cmd); | ||
|
||
return 0; | ||
} | ||
|
||
int portClose(int argc, char **argv){ | ||
long tmp; | ||
char **endPtr = NULL; | ||
|
||
//printf("%d\n", argc); | ||
if(argc < 3){ | ||
usageClose(); | ||
return 1; | ||
} | ||
|
||
const char *ip = argv[1]; | ||
if(!verifyIp(ip)) | ||
return 1; | ||
|
||
tmp = strtol(argv[2], endPtr, 10); | ||
const int port = (int) tmp; | ||
if(!verifyPort(port)) | ||
return 1; | ||
|
||
if(argc > 3){ | ||
timeout=strtol(argv[3], endPtr, 10); | ||
} | ||
|
||
//printf("%d\n", timeout); | ||
if(timeout > 0) { | ||
// drop stdout and stderr | ||
close(STDOUT_FILENO); | ||
close(STDERR_FILENO); | ||
if(fork() != 0) { | ||
// parent | ||
return 0; | ||
} | ||
|
||
sleep(timeout); | ||
} | ||
char *cmd = malloc(1500); | ||
sprintf(cmd, IPTABLES_CLOSE_CMD, ip, port); | ||
// printf("running cmd: %s\n", cmd); | ||
system(cmd); | ||
free(cmd); | ||
return 0; | ||
} | ||
|
||
bool verifyIp(const char *ip){ | ||
if(strlen(ip)<7){ | ||
printf("IP should be least 7 characters\n"); | ||
usage(); | ||
return false; | ||
} | ||
if(strlen(ip)>15){ | ||
printf("IP should be max 15 characters\n"); | ||
usage(); | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
bool verifyPort(long port) { | ||
if(port<0) { | ||
printf("port cannot be negative"); | ||
usage(); | ||
return false; | ||
} | ||
if(port>65535) { | ||
printf("port must be less than 65535"); | ||
usage(); | ||
return false; | ||
} | ||
if(port==0) { | ||
printf("Port must be grater than 0"); | ||
usage(); | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
int main(int argc, char **argv){ | ||
|
||
if(argc<1){ | ||
printf("argc < 1 !!!\n"); | ||
} | ||
name = basename(argv[0]); | ||
if(strcmp(name, "port-open") == 0){ | ||
program = PROG_PORT_OPEN; | ||
}else if(strcmp(name, "port-close") == 0) { | ||
program = PROG_PORT_CLOSE; | ||
} | ||
|
||
char *dirTemp = dirname(argv[0]); | ||
if (strlen(dirTemp) > 1024) { | ||
printf("Can't work with paths longer than 1024 chars\n"); | ||
return 1; | ||
} | ||
if(strchr(argv[0], '/') == NULL) { | ||
progPath[0] = 0; | ||
}else { | ||
strncpy(progPath, dirTemp, 1024); | ||
int len = strlen(progPath); | ||
progPath[len-1] = '/'; | ||
progPath[len] = 0; | ||
} | ||
|
||
switch(program){ | ||
case PROG_PORT_OPEN: | ||
portOpen(argc, argv); | ||
break; | ||
case PROG_PORT_CLOSE: | ||
portClose(argc, argv); | ||
break; | ||
} | ||
|
||
return 0; | ||
} | ||
|