Skip to content

Commit

Permalink
simplify instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
sorbo committed Feb 21, 2016
1 parent 2f4043f commit 35ea3c7
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 114 deletions.
101 changes: 1 addition & 100 deletions INSTALL-Linux.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -86,103 +86,4 @@ iptables firewall setup
=======================

The included `launch_tcpcryptd.sh` script adds iptable rules to divert all TCP
traffic -- *except* that which is already encrypted, like SSH -- to tcpcryptd.
Read on only for more complex firewall setups.

The naive way to use tcpcryptd:

iptables -A OUTPUT -p tcp -j NFQUEUE --queue-num 666
iptables -A INPUT -p tcp -j NFQUEUE --queue-num 666

This will apply tcpcrypt to all locally destined (or generated) TCP packets.
This will work, but you'll run into problems #1 and #2, which may not be
problems if you don't have a firewall or nat setup.

For testing on your local machine, you can restrict tcpcrypt to the loopback interface:

iptables -A OUTPUT -p tcp -o lo -j NFQUEUE --queue-num 666
iptables -A INPUT -p tcp -i lo -j NFQUEUE --queue-num 666

Or, to run tcpcrypt only on port 80, use this (taken from launch_tcpcryptd.sh):

iptables -A OUTPUT -p tcp -m tcp --dport 80 -j NFQUEUE --queue-num 666
iptables -A INPUT -p tcp -m tcp --sport 80 -j NFQUEUE --queue-num 666

To restore your iptables rules to their previous state, you can remove rules by
replacing `-A` (append) with `-D` (delete) in the above commands.

The following instructions apply to using tcpcrypt on firewall/gateway boxes.

Linux firewall setup is more challenging than on FreeBSD for two reasons.

1. In FreeBSD, after a packet is diverted, the divert daemon can drop the
packet, or accept it. In the latter case, firewall processing continues
from the next rule. So basically natd will get a chance to run, and other
firewall rules. It's a pipeline. On Linux, you can either accept or drop
the packet, which ignores the rest of the firewall.

2. In FreeBSD, you can easily order tcpcryptd, then natd, because they're
both in userland, and both use divert, and the whole firewall is a
pipeline. On Linux natd is IP connection tracking in the kernel, which is
used for stateful firewalls too. We gotta make tcpcryptd run BEFORE
conntrack.

To make tcpcrypt work the "proper" way, making sure that nat and stateful
firewalls (e.g., -m state --state ESTABLISHED) work:

iptables -t raw -A PREROUTING -p tcp -j NFQUEUE --queue-num 666
iptables -t mangle -A POSTROUTING -p tcp -j NFQUEUE --queue-num 666

This will apply tcpcrypt to all TCP packets entering and exiting the box,
including forwarded packets. Note that this setup will respect firewall
rules in other tables but terminate those in the raw and mangle tables. In
short, your firewall rules in the filter table and nat table (those that you
probably care about most) will work. You'll get caught by problem #1 though.

To make tcpcrypt work the elite way, making sure that all firewall rules are
obeyed and conntrack isn't confused:

iptables -t raw -N tcpcrypt
iptables -t raw -A tcpcrypt -p tcp -m mark --mark 0x0/0x10 -j NFQUEUE --queue-num 666
iptables -t raw -I PREROUTING -j tcpcrypt

iptables -t mangle -N tcpcrypt
iptables -t mangle -A tcpcrypt -p tcp -m mark --mark 0x0/0x10 -j NFQUEUE --queue-num 666
iptables -t mangle -I POSTROUTING -j tcpcrypt

And launch `tcpcryptd` with `-x 0x10`

This example is like before, but will create a chain with only the tcpcrypt
rule, which will run only if a packet is unmarked. When tcpcryptd needs to
accept a packet, rather than passing a verdict of ACCEPT, which terminates
all rule processing, it will pass a verdict of REPEAT, which restarts
processing at the current chain. To avoid loops, it will also mark the
packet so that the rule to divert will be matched only once. Effectively the
first time round real work will be done, and the second time round we
"return" to process the other rules.

Note that you can make tcpcryptd work transparently on forwarded traffic, and
even in conjunction with NAT. You can pretend that the Internet is
tcpcrypted. Lets say eth0 is your LAN. You can do something like:

[create the tcpcrypt chains as explained earlier.]

iptables -t raw -A PREROUTING -i eth0 -j tcpcrypt
iptables -t mangle -A POSTROUTING -o eth0 -j tcpcrypt

tcpcryptd will see all incoming traffic from eth0 and make it look like
standard TCP to the outside world, and will then tcpcrypt all the responses
coming back to eth0. There's one caveat though when using it in conjunction
with NAT (conntrack). tcpcryptd forges a packet (the INIT2) and this
confuses conntrack as it thinks it's a new connection and it changes the
source port. You therefore need to add:

iptables -t raw -A OUTPUT -o eth0 -j NOTRACK

i.e., all locally generated traffic (the forged packet from tcpcryptd) should
not be natted. In fact I don't even know why it is being natted (maybe a
bug). Of course you need to setup nat with something like:

iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 1.2.3.4

where eth1 is your Internet interface and 1.2.3.4 your Internet static IP.
traffic port 80 to tcpcryptd. See src/iptables.sh for details.
17 changes: 3 additions & 14 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ Installing tcpcrypt
sudo ./launch_tcpcryptd.sh

The launch script starts tcpcryptd and adds firewall rules to divert all TCP
traffic -- *except* that which is already encrypted, like SSH -- to tcpcryptd.
When the script exits (on Ctrl-C or `kill`), it restores your firewall config
to its former state -- *no permanent changes are made*.
traffic on port 80 to tcpcryptd. When the script exits (on Ctrl-C or `kill`),
it restores your firewall config to its former state -- *no permanent changes
are made*.

On Linux, you must first install libnfnetlink, libnetfilter_queue, and libcap.

Expand All @@ -48,17 +48,6 @@ reloading the URL above.
Compare this tcpdump output, which appears encrypted (or at least unreadable),
with the cleartext packets you would see without tcpcryptd running.

A final netcat example:

sudo ./launch_tcpcryptd.sh &
nc -l 7777 &
sudo tcpdump -i lo -n -s0 -vvvv -X tcp port 7777 &
echo hello, world! | nc localhost 7777

# clean up
sudo killall tcpcryptd tcpdump


Troubleshooting
---------------

Expand Down

0 comments on commit 35ea3c7

Please sign in to comment.