All Projects → landhb → DrawBridge

landhb / DrawBridge

Licence: GPL-3.0 license
Layer 4 Single Packet Authentication Linux kernel module utilizing Netfilter hooks and kernel supported Berkeley Packet Filters (BPF)

Programming Languages

c
50402 projects - #5 most used programming language
rust
11053 projects
shell
77523 projects
python
139335 projects - #7 most used programming language
Makefile
30231 projects

Projects that are alternatives of or similar to DrawBridge

portsscan
A web client port-scanner written in GO, that supports the WASM/WASI interface for Browser WebAssembly runtime execution.
Stars: ✭ 68 (-16.05%)
Mutual labels:  knocker, port-knocker, port-knock, port-knocking
Polycube
eBPF/XDP-based software framework for fast network services running in the Linux kernel.
Stars: ✭ 217 (+167.9%)
Mutual labels:  linux-kernel, iptables, bpf
uppersafe-osfw
UPPERSAFE Open Source Firewall
Stars: ✭ 21 (-74.07%)
Mutual labels:  iptables, netfilter
nDPI
Open Source Deep Packet Inspection Software Toolkit
Stars: ✭ 92 (+13.58%)
Mutual labels:  iptables, netfilter
tariq
Hybrid Port Knocking System
Stars: ✭ 20 (-75.31%)
Mutual labels:  port-knock, port-knocking
docker-nfqueue-scapy
Docker container for intercepting packets with scapy from a netfilter queue (nfqueue)
Stars: ✭ 78 (-3.7%)
Mutual labels:  iptables, netfilter
Ebpf exporter
Prometheus exporter for custom eBPF metrics
Stars: ✭ 829 (+923.46%)
Mutual labels:  linux-kernel, bpf
waycup
A minimal tool that hides your online assets from online security scanners, researchers and hackers.
Stars: ✭ 100 (+23.46%)
Mutual labels:  port-knock, port-knocking
portablebpf
You came here so you could have a base code to serve you as an example on how to develop a BPF application, compatible to BCC and/or LIBBPF, specially LIBBPF, having the userland part made in C or PYTHON.
Stars: ✭ 32 (-60.49%)
Mutual labels:  linux-kernel, bpf
ddos-mitigation
Tips to mitigate and secure your large-scale server against DDoS attacks.
Stars: ✭ 58 (-28.4%)
Mutual labels:  iptables
book linuxkernel blockdrv
Learn how multi-queue block device in Linux kernel v4.4 works
Stars: ✭ 69 (-14.81%)
Mutual labels:  linux-kernel
linux
Adding support for the Rust language to the Linux kernel.
Stars: ✭ 3,070 (+3690.12%)
Mutual labels:  linux-kernel
blackip
IP Blocklist for Ipset / Squid-Cache
Stars: ✭ 81 (+0%)
Mutual labels:  iptables
Linux-Kernel-notes
🌟 Notes and codes for Linux Kernel (SJTU-CS353)
Stars: ✭ 21 (-74.07%)
Mutual labels:  linux-kernel
ebpf
eBPF package for Go
Stars: ✭ 25 (-69.14%)
Mutual labels:  bpf
ida-bpf-processor
BPF Processor for IDA Python
Stars: ✭ 41 (-49.38%)
Mutual labels:  bpf
eudyptula
The Eudyptula Challenge
Stars: ✭ 82 (+1.23%)
Mutual labels:  linux-kernel
Linux-System-Management-Scripts-Tricks
Linux Security & Linux Hardening & Linux Management & Linux Configuration
Stars: ✭ 70 (-13.58%)
Mutual labels:  iptables
ipftrace
[Deplicated] Now we have more sophisticated (and compact) implementation in ipftrace2 repository. Please check it as well.
Stars: ✭ 60 (-25.93%)
Mutual labels:  linux-kernel
LAF
Linux Application Firewall
Stars: ✭ 8 (-90.12%)
Mutual labels:  bpf

logo

Actions Status

A layer 4 Single Packet Authentication (SPA) Module, used to conceal TCP/UDP ports on public facing machines and add an extra layer of security.

Note: DrawBridge now supports both IPv4 and IPv6 traffic

Demo

gif

Please read the corresponding article for a more in-depth look at the design.

Basic usage

sudo db auth --server [REMOTE_SERVER] --dport 53 -p udp --unlock [PORT_TO_UNLOCK]

To give the db binary CAP_NET_RAW privs so that you don't need sudo to run it:

chmod 500 ~/.cargo/bin/db
sudo setcap cap_net_raw=pe ~/.cargo/bin/db

It's also convenient to create a bash alias to run db automatically when you want to access the port that it's guarding.

alias "connect"="db auth -s [REMOTE] -d 53 -p udp --unlock [PORT] && ssh -p [PORT] user@[REMOTE]"

CI/CD & Supported Kernel Versions

Kernel Version Build Insmod Tests
5.17.2 Build Insmod Test
5.15.33 Build Insmod Test
5.10.110 Build Insmod Test
5.8.9 Build Insmod Test
5.4.188 Build Insmod Test
4.19.237 Build Insmod Test
4.14.275 Build Insmod Test
4.9.309 Build Insmod Test
4.4.302 Build Insmod Test

Build and Install the Drawbridge Utilities

The usermode tools are now written in Rust! Build and install them with cargo:

git clone https://github.com/landhb/Drawbridge
cargo install --path Drawbridge/tools

# or 
cargo install dbtools

Build and Install the Drawbridge Module

To automagically generate keys, run the following on your client machine:

db keygen

The output of the keygen utility will be three files: ~/.drawbridge/db_rsa, ~/.drawbridge/db_rsa.pub and key.h. Keep db_rsa safe, it's your private key. key.h is the public key formated as a C-header file. It will be compiled into the kernel module.

To compile the kernel module simply, bring key.h, cd into the kernel module directory and run make.

# on the server compile the module and load it
# pass the ports you want to monitor as an argument
mv key.h module/include/
cd module/
make
sudo modprobe x_tables
sudo insmod drawbridge.ko ports=22,445 

You may need to install your kernel headers to compile the module, you can do so with:

sudo apt-get install linux-headers-$(uname -r)
sudo apt-get update && sudo apt-get upgrade

This code has been tested on Linux Kernels between 4.X and 5.9. I don't plan to support anything earlier than 4.X but let me know if you encounter some portabilitity issues on newer kernels.

Customizing a Unique 'knock' Packet

If you wish to customize your knock a little more you can edit the TCP header options in client/bridge.c. For instance, maybe you want to make your knock packet have the PSH,RST,and ACK flags set and a window size of 3104. Turn those on:

// Flags
(*pkt)->tcp_h.fin = 0;   // 1
(*pkt)->tcp_h.syn = 0;   // 2
(*pkt)->tcp_h.rst = 1;   // 4
(*pkt)->tcp_h.psh = 1;   // 8
(*pkt)->tcp_h.ack = 1;   // 16
(*pkt)->tcp_h.urg = 0;   // 32


(*pkt)->tcp_h.window = htons(3104);

Then make sure you can create a BPF filter to match that specific packet. For the above we would have RST(4) + PSH(8) + ACK(16) = 28 and the offset for the window field in the TCP header is 14:

"tcp[tcpflags] == 28 and tcp[14:2] = 3104"

Here is a good short article on tcp flags if you're unfamiliar.. Because tcpdump doesn't support tcp offset shortcuts for IPv6 you have to work with offsets relative to the IPv6 header to support it:

(tcp[tcpflags] == 28 and tcp[14:2] = 3104) or (ip6[40+13] == 28 and ip6[(40+14):2] = 3104)"

After you have a working BPF filter, you need to compile it and include the filter in the kernel module server-side. So to compile this and place the output in kernel/listen.c in struct sock_filter code[]:

tcpdump "(tcp[tcpflags] == 28 and tcp[14:2] = 3104) or (ip6[40+13] == 28 and ip6[(40+14):2] = 3104)" -dd

which gives us:

struct sock_filter code[] = {
	{ 0x28, 0, 0, 0x0000000c },
	{ 0x15, 0, 9, 0x00000800 },
	{ 0x30, 0, 0, 0x00000017 },
	{ 0x15, 0, 13, 0x00000006 },
	{ 0x28, 0, 0, 0x00000014 },
	{ 0x45, 11, 0, 0x00001fff },
	{ 0xb1, 0, 0, 0x0000000e },
	{ 0x50, 0, 0, 0x0000001b },
	{ 0x15, 0, 8, 0x0000001c },
	{ 0x48, 0, 0, 0x0000001c },
	{ 0x15, 5, 6, 0x00000c20 },
	{ 0x15, 0, 5, 0x000086dd },
	{ 0x30, 0, 0, 0x00000043 },
	{ 0x15, 0, 3, 0x0000001c },
	{ 0x28, 0, 0, 0x00000044 },
	{ 0x15, 0, 1, 0x00000c20 },
	{ 0x6, 0, 0, 0x00040000 },
	{ 0x6, 0, 0, 0x00000000 },
};

And there you go! You have a unique packet that the DrawBridge kernel module will parse!

Generating an RSA Key Pair Manually

First generate the key pair:

openssl genrsa -des3 -out private.pem 2048

Export the public key to a seperate file:

openssl rsa -in private.pem -outform DER -pubout -out public.der

If you take a look at the format, you'll see that this doesn't exactly match the kernel struct representation of a public key, so we'll need to extract the relevant data from the BIT_STRING field in the DER format:

vagrant@ubuntu-xenial:~$ openssl asn1parse  -in public.der -inform DER

0:d=0  hl=4 l= 290 cons: SEQUENCE
4:d=1  hl=2 l=  13 cons: SEQUENCE
6:d=2  hl=2 l=   9 prim: OBJECT            :rsaEncryption
17:d=2  hl=2 l=   0 prim: NULL
19:d=1  hl=4 l= 271 prim: BIT STRING        <-------------------- THIS IS WHAT WE NEED

You can see that the BIT_STRING is at offset 19. From here we can extract the relevant portion of the private key format to provide the kernel module:

openssl asn1parse  -in public.der -inform DER -strparse 19 -out output.der

You'll notice that this is compatible with RFC 3447 where it outlines ASN.1 syntax for an RSA public key.

0:d=0  hl=4 l= 266 cons: SEQUENCE
4:d=1  hl=4 l= 257 prim: INTEGER           :BB82865B85ED420CF36054....
265:d=1  hl=2 l=   3 prim: INTEGER           :010001

If you need to dump output.der as a C-style byte string:

hexdump -v -e '16/1 "_x%02X" "\n"' output.der | sed 's/_/\\/g; s/\\x  //g; s/.*/    "&"/'
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].