5

I'd like to make a git-daemon go through a permanent ssh tunnel. I accomplished this task. How do I block any remote untunneled connection to the GIT_DAEMON port (9418 in my case)?

I already tried simple rules in iptables (block everything except localhost):

$ iptables -A INPUT -p tcp -d ! localhost --destination-port 9418 -j DROP

But it also blocks a tunnel (since it saves source ip address). If I have one more host for firewall it can be simply done by blocking any remote connection to this port, but I need this host to do this job.

The tunnel is created in one of two ways:

For Windows:

plink.exe -N -i <key> -L 127.0.0.1:9418:192.168.1.69:9418 tunnel@192.168.1.69

For Linux:

ssh -N -i <key> -L 127.0.0.1:9418:192.168.1.69:9418 tunnel@192.168.1.69
Ben Burns
  • 14,978
  • 4
  • 35
  • 56
kravitz
  • 973
  • 2
  • 10
  • 22

2 Answers2

7

You can actually achieve this without using iptables at all, by simply making git-daemon bind to the loopback interface, eg.

git daemon --listen=127.0.0.1

This will make it so it is only connectable from localhost, and does not require root privileges to set up.

Hasturkun
  • 35,395
  • 6
  • 71
  • 104
  • thanks, clean and simple. But @cnicutar's advice with correct tunneling deserves "correct answer" mark. – kravitz Jun 12 '11 at 09:54
4

You might try this (untested):

# accept localhost
iptables -A INPUT -p tcp -d localhost --destination-port 9418 -j ACCEPT

# send everyone else packing
iptables -A INPUT -p tcp --destination-port 9418 -j DROP

Using that iptables -L says:

ACCEPT     tcp  --  anywhere             localhost.localdomain tcp dpt:git
DROP       tcp  --  anywhere             anywhere            tcp dpt:git

EDIT

This is (probably) how your tunnel should be setup:

ssh -N -i <key> -L 127.0.0.1:9418:127.0.0.1:9418 tunnel@192.168.1.69

It's important that the second half is 127.0.0.1 and NOT a normal IP

cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • Now its tested, but isn't too helpful, it provides same effect as rule in a question :( – kravitz Jun 12 '11 at 08:09
  • @kravitz Can you explain a little better what the path of the traffic should be ? – cnicutar Jun 12 '11 at 08:10
  • @cnicutar sure, suppose we have three hosts: A, B, C. Host A has a git-daemon running, host B wants to communicate with A (push/pull requests), host C shouldn't be able to access git-daemon at A. I emulate authentication via ssh tunneling. So B creates local tunnel to A (9418 port to 9418, with -L option in openssh), it means that everything that B sends to a local 9418 port goes through ssh (22 port) and occurs at A's 9418 port. I need a filtration mechanism, that will block connections to A:9418, for everything, except tunnels. – kravitz Jun 12 '11 at 08:18
  • @kravitz I edited my answer. Do you have the tunnel setup _exactly_ that way ? It's very possible to do it with `iptables`, be patient. – cnicutar Jun 12 '11 at 08:27
  • @cnicutar yes, absolutely that way. I also give -N option, to make a non-interactive session. Also tried to connect with a Windows host, with tunnel, made by plink. Both OpenSSH and Plink works smoothly unless I enable filter rules. – kravitz Jun 12 '11 at 08:37
  • @kravitz I see in your question that the tunner is NOT created **exactly** the way I said. **It should be `127.0.0.1` instead of `192.168.1.69`**. – cnicutar Jun 12 '11 at 08:44
  • @cnicutar my bad :) I tried your suggestion and it works, thanks a lot, also you can edit your answer, that this tunnel must be setup from B, because it wasn't clear for me, and I first tried it on A, and get nothing interesting. And my one-line rule works :) – kravitz Jun 12 '11 at 08:48