Skip to content

Commit

Permalink
added project files v0.5
Browse files Browse the repository at this point in the history
  • Loading branch information
npelov committed Dec 7, 2019
1 parent 4e5fb73 commit 0e72919
Show file tree
Hide file tree
Showing 6 changed files with 358 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitattributes
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
4 changes: 4 additions & 0 deletions .gitignore
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
Expand Down
63 changes: 63 additions & 0 deletions Makefile
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
50 changes: 50 additions & 0 deletions README.md
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)

31 changes: 31 additions & 0 deletions knockd-example.conf
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

206 changes: 206 additions & 0 deletions port-open.c
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;
}

0 comments on commit 0e72919

Please sign in to comment.