Skip to content

Commit 05ac770

Browse files
committed
Initial commit.
0 parents  commit 05ac770

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Copyright 2010 Garret Kelly. All Rights Reserved.
2+
# Author: [email protected] (Garret Kelly)
3+
4+
obj-m += upk.o
5+
6+
all:
7+
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
8+
9+
clean:
10+
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

upk.c

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Copyright 2010 Garret Kelly. All Rights Reserved.
2+
// Author: [email protected] (Garret Kelly)
3+
4+
#include <linux/module.h>
5+
6+
#include <linux/tcp.h>
7+
#include <linux/ip.h>
8+
#include <linux/netfilter.h>
9+
#include <linux/netfilter_ipv4.h>
10+
#include <linux/skbuff.h>
11+
12+
MODULE_AUTHOR("Garret Kelly");
13+
MODULE_LICENSE("GPL v2");
14+
MODULE_DESCRIPTION("A tiny port-knocking implementation that guards a single "
15+
"port from access with a user-specified knocking sequence");
16+
MODULE_PARM_DESC(upk_protected_port, "The port to which access will be denied "
17+
"until the correct knocking sequence is recieved");
18+
MODULE_PARM_DESC(upk_timeout, "The timeout, in jiffies, before the entered "
19+
"sequence resets itself if it has not been completed");
20+
MODULE_PARM_DESC(upk_sequence, "The sequence of ports that must be 'knocked' "
21+
"upon for the protected port to be made accessbile");
22+
23+
#define UPK_MAX_SEQUENCE_LENGTH 10
24+
#define UPK_INFO KERN_INFO "upk: "
25+
26+
static int upk_protected_port = 22;
27+
static int upk_timeout = 5 * HZ;
28+
static int upk_sequence[UPK_MAX_SEQUENCE_LENGTH] = {1234, 4321, 4444, 0};
29+
static int upk_sequence_length = UPK_MAX_SEQUENCE_LENGTH;
30+
31+
module_param(upk_protected_port, int, 0);
32+
module_param(upk_timeout, int, 0);
33+
module_param_array(upk_sequence, int, &upk_sequence_length, 0);
34+
35+
static int upk_open = false;
36+
static int upk_sequence_index = 0;
37+
static unsigned long upk_sequence_timestamp = 0;
38+
static struct nf_hook_ops upk_netfilter_hook;
39+
40+
static void upk_reset(void)
41+
{
42+
upk_open = false;
43+
upk_sequence_index = 0;
44+
upk_sequence_timestamp = 0;
45+
}
46+
47+
static unsigned int upk_filter_function(unsigned int hooknum,
48+
struct sk_buff *skb, const struct net_device *in,
49+
const struct net_device *out, int (*okfn)(struct sk_buff *))
50+
{
51+
struct iphdr *ip_header;
52+
struct tcphdr *tcp_header;
53+
54+
ip_header = ip_hdr(skb);
55+
if (!ip_header || ip_header->protocol != IPPROTO_TCP) {
56+
return NF_ACCEPT;
57+
}
58+
59+
tcp_header = (struct tcphdr *)(skb->data + (ip_header->ihl * 4));
60+
if (tcp_header->dest == htons(upk_protected_port)) {
61+
if (upk_open) {
62+
return NF_ACCEPT;
63+
}
64+
return NF_DROP;
65+
} else {
66+
if ((jiffies - upk_sequence_timestamp) > upk_timeout) {
67+
upk_reset();
68+
}
69+
if (tcp_header->dest == htons(upk_sequence[upk_sequence_index])) {
70+
upk_sequence_timestamp = jiffies;
71+
upk_sequence_index++;
72+
if (upk_sequence[upk_sequence_index] == 0) {
73+
upk_open = true;
74+
}
75+
}
76+
}
77+
78+
return NF_ACCEPT;
79+
}
80+
81+
static int __init upk_init(void)
82+
{
83+
upk_reset();
84+
upk_sequence[upk_sequence_length] = 0;
85+
86+
upk_netfilter_hook.hook = upk_filter_function;
87+
upk_netfilter_hook.hooknum = NF_INET_PRE_ROUTING;
88+
upk_netfilter_hook.pf = PF_INET;
89+
upk_netfilter_hook.priority = NF_IP_PRI_FIRST;
90+
nf_register_hook(&upk_netfilter_hook);
91+
92+
printk(UPK_INFO "loaded\n");
93+
94+
return 0;
95+
}
96+
97+
static void __exit upk_exit(void)
98+
{
99+
nf_unregister_hook(&upk_netfilter_hook);
100+
101+
printk(UPK_INFO "unloaded\n");
102+
}
103+
104+
module_init(upk_init);
105+
module_exit(upk_exit);

0 commit comments

Comments
 (0)