KNOCK_NAME=$1 PORT_1=$2 PORT_2=$3 PORT_3=$4 PORT_4=$5 OPEN_PORT=$6 OPEN_TIME=$7 PHASE_1=p1_$KNOCK_NAME PHASE_2=p2_$KNOCK_NAME PHASE_3=p3_$KNOCK_NAME PHASE_4=p4_$KNOCK_NAME JUMP_TO_2=j2_$KNOCK_NAME JUMP_TO_3=j3_$KNOCK_NAME JUMP_TO_4=j4_$KNOCK_NAME iptables -X $JUMP_TO_2 iptables -N $JUMP_TO_2 iptables -A $JUMP_TO_2 -m recent --name $PHASE_1 --remove iptables -A $JUMP_TO_2 -m recent --name $PHASE_2 --set iptables -X $JUMP_TO_3 iptables -N $JUMP_TO_3 iptables -A $JUMP_TO_3 -m recent --name $PHASE_2 --remove iptables -A $JUMP_TO_3 -m recent --name $PHASE_3 --set iptables -X $JUMP_TO_4 iptables -N $JUMP_TO_4 iptables -A $JUMP_TO_4 -m recent --name $PHASE_3 --remove iptables -A $JUMP_TO_4 -m recent --name $PHASE_4 --set iptables -A INPUT -m recent --update --name $PHASE_1 iptables -A INPUT -p udp --dport $PORT_1 -m recent --set --name $PHASE_1 iptables -A INPUT -p udp --dport $PORT_2 -m recent --rcheck --name $PHASE_1 -j $JUMP_TO_2 iptables -A INPUT -p udp --dport $PORT_3 -m recent --rcheck --name $PHASE_2 -j $JUMP_TO_3 iptables -A INPUT -p udp --dport $PORT_4 -m recent --rcheck --name $PHASE_3 -j $JUMP_TO_4 iptables -A INPUT -p tcp --dport $OPEN_PORT -m recent --rcheck --seconds $OPEN_TIME --name $PHASE_4 -j ACCEPT
In this example I'm actually using UDP ports, because they are easier to knock on: no attempt is made to actually connect and (thus) timeout. If you prefer TCP knocking, and you don't know how to adjust the script, click here.
# setup all rules you currently have ... (important stuff!) # add (several) port knocking triggers ./iptables-knocking.sh mail2 108 107 106 105 9992 15 ./iptables-knocking.sh mail3 101 102 103 104 9993 15 | | | | | | -> timeout_to_close name | | port3 | port_to_open port1 | | port2 port4 # reject everything else iptables -A INPUT -s 0/0 -d 0/0 -j REJECT
When working with IPTABLES, keep paying attention. It's WAY too easy to lock yourself out or 'ruin your uptime' one way or another. Needless to say, I am in no way responsible for any problems or damages that are the result of the usage of the above code. You have been warned.
Next up, a trivial Java portknocking client:
public static void knockUDP(String hostname, int... ports) { DatagramSocket socket = new DatagramSocket(); for(int port: ports) { // account for a bit of packet loss for(int i=0; i<4; i++) { socket.send(new DatagramPacket(new byte[1], 1, new InetSocketAddress(hostname, port))); } // try to make it more likely the packets arrive in-order Thread.sleep(100); } } public static void knockTCP(String hostname, int... ports) { for(int port: ports) { Socket s = new Socket(); try { s.connect(new InetSocketAddress(hostname, port), 100); s.close(); // it appears we actually connected, which is not what we wanted.... } catch( IOException) { // ignore, really! } } } knockUDP("your-public-server.com", 101, 102, 103, 104); knockTCP("your-public-server.com", 101, 102, 103, 104);
thanks man! gr8 example.
ReplyDelete