1/2 Kg o 3/4Kg para 3 personas.
Se pica en trozos (tacos)
En la olla se añade aceite, se pic acebolla, ajo .. una vez dorado se añade la carne y se rehoga. Cuando ya esta, se añade vino blanco, agua, pimienta, perejil, laurel, zanahoria (trozos grandes) y una pastilla de caldo.
Se cierra la olla y se deja unos 16 - 18 min.
A parte se pueden cocer o freir patatas en tacos y añadir al resultado.
Cosas de la vida
domingo, 10 de octubre de 2010
Sopa de pescado
En una olla se echan en agua las raspas, cabeza, y restos del pescado que no se hayan usado anteriormente.
Se añade laurel, 1 zanahoria, puerro, cebolla (1/2) ajo, tomillo, ... y sal
Se deja cocer unos 5 minutos en la olla (presion 2)
Se cuela el líquido y se reserva.
Se puede cocer un huevo.
En otra cazuela, se frie cebolla picada, ajo, perejil, pimiento (muy menudito). Se añade el caldo colado, vino blanco (chorrito), 1 o 2 cucharadas de tomate frito y se pueda añadir una pastilla de caldo de pez.
Cuando hierve se añaden los fiedos.
Se pueden añadir tropezones a gusto (gambas, palitos de mar, etc etc etc ..)
Se añade laurel, 1 zanahoria, puerro, cebolla (1/2) ajo, tomillo, ... y sal
Se deja cocer unos 5 minutos en la olla (presion 2)
Se cuela el líquido y se reserva.
Se puede cocer un huevo.
En otra cazuela, se frie cebolla picada, ajo, perejil, pimiento (muy menudito). Se añade el caldo colado, vino blanco (chorrito), 1 o 2 cucharadas de tomate frito y se pueda añadir una pastilla de caldo de pez.
Cuando hierve se añaden los fiedos.
Se pueden añadir tropezones a gusto (gambas, palitos de mar, etc etc etc ..)
Pescadilla / Merluza a la Nati
Se puede pedir en rajas o en filetes (sin raspa).
Si se piede en trozos:
1) Se echa sal y se unta en harina
2) Se frien los trozos.
Una vez fritos, con el mismo aceite,
3) picar cebolla (1/2) y 1/2 diente de ajo (opcional)
4) Cuando la cebolla esta dorada, añadir vino blanco, agua, laurel
5) Añadir los trozos de pescado, y dejar que se haga todo junto un rato.
Se puede añadir salsa de tomate frito casero.
Si se piede en filetes,
se reboza: sal + harina + huevo y a la sarten
Si se piede en trozos:
1) Se echa sal y se unta en harina
2) Se frien los trozos.
Una vez fritos, con el mismo aceite,
3) picar cebolla (1/2) y 1/2 diente de ajo (opcional)
4) Cuando la cebolla esta dorada, añadir vino blanco, agua, laurel
5) Añadir los trozos de pescado, y dejar que se haga todo junto un rato.
Se puede añadir salsa de tomate frito casero.
Si se piede en filetes,
se reboza: sal + harina + huevo y a la sarten
martes, 27 de julio de 2010
domingo, 4 de julio de 2010
TCPDUMP filters
common Filters
ip IP
arp arp
tcp tcp
udp udp
icmp icmp
ip multicast IP Multicast
ether multicast Ethernet Multicast
IP Filters
ip[0] & 0x0f low nibble: header length in 4octet words. should be 5
ip[1] type of service/QoS/DiffServ
ip[2:2] total length of datagram in octets
ip[4:2] IP ID number
ip[6] & 0x80 reserved bit (possibly used for ECN)
ip[6] & 0x40 DF bit
ip[6] & 0x20 MF bit
ip[6:2] & 0x1fff fragment offset (number of 8octet blocks)
ip[8] ttl
ip[9] protocol
ip[10:2] header checksum
ip[12:4] source IP
ip[16:4] destination IP
Samples
(ip[12:4] = ip[16:4]) Src IP = Dest IP (land attack)
ip[0] & 0xf0 high nibble: IP version. almost always 4
(ip[0] & 0xf0 != 0x40) IP versions !=4
(ip[0:1] & 0x0f > 5) IP with options set
(ip[19] = 0xff) Broadcasts to x.x.x.255
(ip[19] = 0x00) Broadcasts to x.x.x.0
(ip and ip[1] & 0xfc == 0xb8) search for EF in DSCP
(ip and ip[1] & 0xfc == 0x28) search for AF11 in DSCP
(ip and ip[1] & 0xfc != 0x00) search for DCSP Packets != 0
(ip[6] & 0x20 != 0) && (ip[6:2] & 0x1fff = 0) initial fragments
(ip[6] & 0x20 != 0) && (ip[6:2] & 0x1fff != 0) intervening fragments
(ip[6] & 0x20 = 0) && (ip[6:2] & 0x1fff != 0) terminal fragments
(ip[0] & 0x0f) != 5 has ip options (or is truncated, or is just some sort of freak...)
ip[8] < 5 short TTL value
ip[6] = 32 MF set
iip[2:2] > 999 IP Packet greater then 999
ICMP Filters
icmp[0] type
icmp[1] code
icmp[2:2] checksum
Samples
icmp[0]=0x# all Packets with ICMP Type
icmp[0]=0x# and icmp[1]=0x# all Packets with ICMP Type X and Code = Y
icmp[0]=8 ICMP Request Messages
icmp[8]=0 ICMP Request Replay
icmp[0]=0x11 ICMP Address Mask Request
icmp[0]=0x12 ICMP Address Mask Replay
icmp[0]=11 and icmp[1]=0 ICMP Time Exeedet
icmp[0]=3 and icmp[1]=4 ICMP Time Exeedet
icmp[0]=8 and ip[2:2] > 64 Large ICMP Packets
TCP Filters
tcp[0:2] source port
tcp[2:2] destination port
tcp[4:4] sequence number
tcp[8:4] ack number
tcp[12] header length
tcp[13] tcp flags
---- --S- 0000 0010 = 0x02 normal syn
---A --S- 0001 0010 = 0x12 normal syn-ack
---A ---- 0001 0000 = 0x10 normal ack
--UA P--- 0011 1000 = 0x38 psh-urg-ack. interactive stuff like ssh
---A -R-- 0001 0100 = 0x14 rst-ack. it happens.
---- --SF 0000 0011 = 0x03 syn-fin scan
--U- P--F 0010 1001 = 0x29 urg-psh-fin. nmap fingerprint packet
-Y-- ---- 0100 0000 = 0x40 anything >= 0x40 has a reserved bit set
XY-- ---- 1100 0000 = 0xC0 both reserved bits set
XYUA PRSF 1111 1111 = 0xFF FULL_XMAS scan
tcp[14:2] window size
tcp[16:2] checksumt
tcp[18:2] urgent pointer
Samples
tcp[13] = 0x02 is SYN. nothing else.
(tcp[13] & 0x02) != 0 contains SYN. we don't care what else...
(tcp[13] & 0x03) = 3 is some kind of SYN-FIN. realy Bad
winnuke (not tested)
tcp[20:4] = 0x47455420 GET in request
UDP Filters
udp[0:2] source port
udp[2:2] destination port
udp[4:2] datagram length
udp[6:2] UDP checksum
protocols
ip[9] == 8 EGP
ip[9] == 9 IGP
ip[9] == 88 EIRGP
ip[9] == 50 ESP
ip[9] == 51 AH
ip[9] == 89 OSPF
ip[9] == 124 ISIS
other, see /etc/protocols
Routing Protocols
(udp and port 520) or (host 224.0.0.9) RIP 1 + 2
tcp and port 179 BGP
ip[9] == 8 EGP
ip[9] == 9 IGP
ip[9] == 88 EIRGP
ip[9] == 89 OSPF
ip[9] == 124 ISIS
ether Filters
ether[20:2] == 0x2000 CDP pakets
ether[12:2] == 0x0806 ARP pakets
IPv6
ip6 filters native IPv6 traffic (including ICMPv6)
icmp6 filters native ICMPv6 traffic
proto ipv6 filters tunneled IPv6-in-IPv4 traffic
TCP
ip6 and (ip6[6] == 0x06) IPv6 TCP
ip6 and (ip6[6] == 0x06) and (ip6[53] == 0x02) IPv6 TCP Syn
ip6 and (ip6[6] == 0x06) and (ip6[53] == 0x10) IPv6 TCP ACK
ip6 and (ip6[6] == 0x06) and (ip6[53] == 0x12) IPv6 TCP Syn/ACK
UDP
ip6 and (ip6[6] == 0x11) IPv6 TCP
ICMP
(ip6[6] == 0x3a) ICMP v6
(ip6[6] == 0x3a) and (ip6[40] == 0x01) ipv6 and type 1 Dest Unreachable
(ip6[6] == 0x3a) and (ip6[40] == 0x02) ipv6 and type 2 Packet too big
(ip6[6] == 0x3a) and (ip6[40] == 0x03) ipv6 and type 3 Time Exeedet
(ip6[6] == 0x3a) and (ip6[40] == 0x04) ipv6 and type 4 Parameter Problem
(ip6[6] == 0x3a) and (ip6[40] == 0x80) ipv6 and type 128 Echo Request
(ip6[6] == 0x3a) and (ip6[40] == 0x81) ipv6 and type 129 Echo Reply
(ip6[6] == 0x3a) and (ip6[40] == 0x86) ipv6 and type 133 Router Solicitation
(ip6[6] == 0x3a) and (ip6[40] == 0x87) ipv6 and type 134 Router Advertisement
(ip6[6] == 0x3a) and (ip6[40] == 0x88) ipv6 and type 135 Neighbor Solicitation
(ip6[6] == 0x3a) and (ip6[40] == 0x89) ipv6 and type 136 Neighbor Advertisement
Basic syntax :
==============
Filtering hosts :
-----------------
- Match any traffic involving 192.168.1.1 as destination or source
# tcpdump -i eth1 host 192.168.1.1
- As soure only
# tcpdump -i eth1 src host 192.168.1.1
- As destination only
# tcpdump -i eth1 dst host 192.168.1.1
Filtering ports :
-----------------
- Match any traffic involving port 25 as source or destination
# tcpdump -i eth1 port 25
- Source
# tcpdump -i eth1 src port 25
- Destination
# tcpdump -i eth1 dst port 25
Network filtering :
-------------------
# tcpdump -i eth1 net 192.168
# tcpdump -i eth1 src net 192.168
# tcpdump -i eth1 dst net 192.168
Protocol filtering :
--------------------
# tcpdump -i eth1 arp
# tcpdump -i eth1 ip
# tcpdump -i eth1 tcp
# tcpdump -i eth1 udp
# tcpdump -i eth1 icmp
Let's combine expressions :
---------------------------
Negation : ! or "not" (without the quotes)
Concatanate : && or "and"
Alternate : || or "or"
- This rule will match any TCP traffic on port 80 (web) with 192.168.1.254 or 192.168.1.200 as destination host
# tcpdump -i eth1 '((tcp) and (port 80) and ((dst host 192.168.1.254) or (dst host 192.168.1.200)))'
- Will match any ICMP traffic involving the destination with physical/MAC address 00:01:02:03:04:05
# tcpdump -i eth1 '((icmp) and ((ether dst host 00:01:02:03:04:05)))'
- Will match any traffic for the destination network 192.168 except destination host 192.168.1.200
# tcpdump -i eth1 '((tcp) and ((dst net 192.168) and (not dst host 192.168.1.200)))'
Advanced header filtering :
===========================
Before we continue, we need to know how to filter out info from headers
proto[x:y] : will start filtering from byte x for y bytes. ip[2:2] would filter bytes 3 and 4 (first byte begins by 0)
proto[x:y] & z = 0 : will match bits set to 0 when applying mask z to proto[x:y]
proto[x:y] & z !=0 : some bits are set when applying mask z to proto[x:y]
proto[x:y] & z = z : every bits are set to z when applying mask z to proto[x:y]
proto[x:y] = z : p[x:y] has exactly the bits set to z
Operators : >, <, >=, <=, =, !=
This may not be clear in the first place but you'll find examples below involving these.
Of course, it is important to know what the protocol headers look like before diving into more advanced filters.
IP header
---------
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding | <-- optional
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| DATA ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
I'll consider we are only working with the IPv4 protocol suite for these examples.
In an ideal world, every field would fit inside one byte. This is not the case, of course.
Are IP options set ?
--------------------
Let's say we want to know if the IP header has options set. We can't just try to filter out the 21st byte
because if no options are set, data start at the 21st byte. We know a "normal" header is usually 20 bytes
(160 bits) long. With options set, the header is longer than that. The IP header has the header
length field which we will filter here to know if the header is longer than 20 bytes.
+-+-+-+-+-+-+-+-+
|Version| IHL |
+-+-+-+-+-+-+-+-+
Usually the first byte has a value of 01000101 in binary.
Anyhow, we need to divide the first byte in half...
0100 = 4 in decimal. This is the IP version.
0101 = 5 in decimal. This is the number of blocks of 32 bits in the headers. 5 x 32 bits = 160 bits or 20 bytes.
The second half of the first byte would be bigger than 5 if the header had IP options set.
We have two ways of dealing with that kind of filters.
1. Either try to match a value bigger than 01000101. This would trigger matches for IPv4 traffic with IP options set,
but ALSO any IPv6 traffic !
In decimal 01000101 equals 69.
Let's recap how to calculate in decimal.
0 : 0 \
1 : 2^6 = 64 \ First field (IP version)
0 : 0 /
0 : 0 /
-
0 : 0 \
1 : 2^2 = 4 \ Second field (Header length)
0 : 0 /
1 : 2^0 = 1 /
64 + 4 + 1 = 69
The first field in the IP header would usually have a decimal value of 69.
If we had IP options set, we would probably have 01000110 (IPv4 = 4 + header = 6), which in decimal equals 70.
This rule should do the job :
# tcpdump -i eth1 'ip[0] > 69'
Somehow, the proper way is to mask the first half/field of the first byte, because as mentionned earlier,
this filter would match any IPv6 traffic.
2. The proper way : masking the first half of the byte
0100 0101 : 1st byte originally
0000 1111 : mask (0x0f in hex or 15 in decimal). 0 will mask the values while 1 will keep the values intact.
=========
0000 0101 : final result
The correct filter :
# tcpdump -i eth1 'ip[0] & 15 > 5'
or
# tcpdump -i eth1 'ip[0] & 0x0f > 5'
DF bit (don't fragment) set ?
-----------------------------
Let's now trying to know if we have fragmentation occuring, which is not desirable. Fragmentation occurs
when a the MTU of the sender is bigger than the path MTU on the path to destination.
Fragmentation info can be found in the 7th and 8th byte of the IP header.
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Bit 0: reserved, must be zero
Bit 1: (DF) 0 = May Fragment, 1 = Don't Fragment.
Bit 2: (MF) 0 = Last Fragment, 1 = More Fragments.
The fragment offset field is only used when fragmentation occurs.
If we want to match the DF bit (don't fragment bit, to avoid IP fragmentation) :
The 7th byte would have a value of :
01000000 or 64 in decimal
# tcpdump -i eth1 'ip[6] = 64'
Matching fragmentation ?
------------------------
- Matching MF (more fragment set) ? This would match the fragmented datagrams but wouldn't match the last
fragment (which has the 2nd bit set to 0).
# tcpdump -i eth1 'ip[6] = 32'
The last fragment have the first 3 bits set to 0... but has data in the fragment offset field.
- Matching the fragments and the last fragments
# tcpdump -i eth1 '((ip[6:2] > 0) and (not ip[6] = 64))'
A bit of explanations :
"ip[6:2] > 0" would return anything with a value of at least 1
We don't want datagrams with the DF bit set though.. the reason of the "not ip[6] = 64"
If you want to test fragmentation use something like :
ping -M want -s 3000 192.168.1.1
Matching datagrams with low TTL
-------------------------------
The TTL field is located in the 9th byte and fits perfectly into 1 byte.
The maximum decimal value of the TTL field is thus 255 (11111111 in binary).
This can be verified :
$ ping -M want -s 3000 -t 256 192.168.1.200
ping: ttl 256 out of range
+-+-+-+-+-+-+-+-+
| Time to Live |
+-+-+-+-+-+-+-+-+
We can try to find if someone on our network is using traceroute by using something like this on the gateway :
# tcpdump -i eth1 'ip[8] < 5'
Matching packets longer than X bytes
------------------------------------
Where X is 600 bytes
# tcpdump -i eth1 'ip[2:2] > 600'
More IP filtering
-----------------
We could imagine filtering source and destination addresses directly in decimal addressing.
We could also match the protocol by filtering the 10th byte.
It would be pointless anyhow, because tcpdump makes it already easy to filter out that kind of info.
TCP header
----------
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |C|E|U|A|P|R|S|F| |
| Offset| Res. |W|C|R|C|S|S|Y|I| Window |
| | |R|E|G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Matching any TCP traffic with a source port > 1024
# tcpdump -i eth1 'tcp[0:2] > 1024'
- Matching TCP traffic with particular flag combinations
The flags are defined in the 14th byte of the TCP header.
+-+-+-+-+-+-+-+-+
|C|E|U|A|P|R|S|F|
|W|C|R|C|S|S|Y|I|
|R|E|G|K|H|T|N|N|
+-+-+-+-+-+-+-+-+
In the TCP 3-way handshakes, the exchange between hosts goes like this :
1. Source sends SYN
2. Destination answers with SYN, ACK
3. Source sends ACK
- If we want to match packets with only the SYN flag set, the 14th byte would have a binary
value of 00000010 which equals 2 in decimal.
# tcpdump -i eth1 'tcp[13] = 2'
- Matching SYN, ACK (00010010 or 18 in decimal)
# tcpdump -i eth1 'tcp[13] = 18'
- Matching either SYN only or SYN-ACK datagrams
# tcpdump -i eth1 'tcp[13] & 2 = 2'
We used a mask here. It will returns anything with the ACK bit set (thus the SYN-ACK combination as well)
Let's assume the following examples (SYN-ACK)
00010010 : SYN-ACK packet
00000010 : mask (2 in decimal)
--------
00000010 : result (2 in decimal)
Every bits of the mask match !
- Matching PSH-ACK packets
# tcpdump -i eth1 'tcp[13] = 24'
- Matching any combination containing FIN (FIN usually always comes with an ACK so we either
need to use a mask or match the combination ACK-FIN)
# tcpdump -i eth1 'tcp[13] & 1 = 1'
- Matching RST flag
# tcpdump -i eth1 'tcp[13] & 4 = 4'
By looking at the TCP state machine diagram (http://www.wains.be/pub/networking/tcp_state_machine.jpg)
we can find the different flag combinations we may want to analyze.
Ideally, a socket in ACK_WAIT mode should not have to send a RST. It means the 3 way handshake has not completed.
We may want to analyze that kind of traffic.
Matching SMTP data :
--------------------
I will make a filter that will match any packet containing the "MAIL" command from SMTP exchanges.
I use something like http://www.easycalculation.com/ascii-hex.php to convert values from ASCII to hexadecimal.
"MAIL" in hex is 0x4d41494c
The rule would be :
# tcpdump -i eth1 '((port 25) and (tcp[20:4] = 0x4d41494c))'
It will check the bytes 21 to 24. "MAIL" is 4 bytes/32 bits long..
This rule would not match packets with IP options set.
This is an example of packet (a spam, of course) :
# tshark -V -i eth0 '((port 25) and (tcp[20:4] = 0x4d41494c))'
Capturing on eth0
Frame 1 (92 bytes on wire, 92 bytes captured)
Arrival Time: Sep 25, 2007 00:06:10.875424000
[Time delta from previous packet: 0.000000000 seconds]
[Time since reference or first frame: 0.000000000 seconds]
Frame Number: 1
Packet Length: 92 bytes
Capture Length: 92 bytes
[Frame is marked: False]
[Protocols in frame: eth:ip:tcp:smtp]
Ethernet II, Src: Cisco_X (00:11:5c:X), Dst: 3Com_X (00:04:75:X)
Destination: 3Com_X (00:04:75:X)
Address: 3Com_X (00:04:75:X)
.... ...0 .... .... .... .... = IG bit: Individual address (unicast)
.... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
Source: Cisco_X (00:11:5c:X)
Address: Cisco_X (00:11:5c:X)
.... ...0 .... .... .... .... = IG bit: Individual address (unicast)
.... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
Type: IP (0x0800)
Internet Protocol, Src: 62.163.X (62.163.X), Dst: 192.168.X (192.168.X)
Version: 4
Header length: 20 bytes
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
0000 00.. = Differentiated Services Codepoint: Default (0x00)
.... ..0. = ECN-Capable Transport (ECT): 0
.... ...0 = ECN-CE: 0
Total Length: 78
Identification: 0x4078 (16504)
Flags: 0x04 (Don't Fragment)
0... = Reserved bit: Not set
.1.. = Don't fragment: Set
..0. = More fragments: Not set
Fragment offset: 0
Time to live: 118
Protocol: TCP (0x06)
Header checksum: 0x08cb [correct]
[Good: True]
[Bad : False]
Source: 62.163.X (62.163.X)
Destination: 192.168.X (192.168.XX)
Transmission Control Protocol, Src Port: 4760 (4760), Dst Port: smtp (25), Seq: 0, Ack: 0, Len: 38
Source port: 4760 (4760)
Destination port: smtp (25)
Sequence number: 0 (relative sequence number)
[Next sequence number: 38 (relative sequence number)]
Acknowledgement number: 0 (relative ack number)
Header length: 20 bytes
Flags: 0x18 (PSH, ACK)
0... .... = Congestion Window Reduced (CWR): Not set
.0.. .... = ECN-Echo: Not set
..0. .... = Urgent: Not set
...1 .... = Acknowledgment: Set
.... 1... = Push: Set
.... .0.. = Reset: Not set
.... ..0. = Syn: Not set
.... ...0 = Fin: Not set
Window size: 17375
Checksum: 0x6320 [correct]
[Good Checksum: True]
[Bad Checksum: False]
Simple Mail Transfer Protocol
Command: MAIL FROM:\r\n
Command: MAIL
Request parameter: FROM:
Matching HTTP data :
--------------------
Let's make a filter that will find any packets containing GET requests
The HTTP request will begin by :
GET / HTTP/1.1\r\n (16 bytes counting the carriage return but not the backslashes !)
If no IP options are set.. the GET command will use the byte 20, 21 and 22
Tcpdump is only able to match data size of either 1, 2 or 4 bytes, we will take the following ASCII
character following the GET command (a space)
"GET " in hex : 47455420
# tcpdump -i eth1 'tcp[20:4] = 0x47455420'
Matching other interesting TCP things :
---------------------------------------
SSH connection (on any port) :
We will be looking for the reply given by the SSH server.
OpenSSH usually replies with something like "SSH-2.0-OpenSSH_3.6.1p2".
The first 4 bytes (SSH-) have an hex value of 0x5353482D.
# tcpdump -i eth1 'tcp[(tcp[12]>>2):4] = 0x5353482D'
If we want to find any connection made to older version of OpenSSH (version 1, which are insecure and subject to MITM attacks) :
The reply from the server would be something like "SSH-1.99.."
# tcpdump -i eth1 '(tcp[(tcp[12]>>2):4] = 0x5353482D) and (tcp[((tcp[12]>>2)+4):2] = 0x312E)'
UDP header
----------
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| Source | Destination |
| Port | Port |
+--------+--------+--------+--------+
| | |
| Length | Checksum |
+--------+--------+--------+--------+
| |
| DATA ... |
+-----------------------------------+
Nothing really interesting here.
If we want to filter ports we would use something like :
# tcpdump -i eth1 udp dst port 53
ICMP header
-----------
See different ICMP messages :
http://img292.imageshack.us/my.php?image=icmpmm6.gif
We will usually filter the type (1 byte) and code (1 byte) of the ICMP messages.
Here are common ICMP types :
0 Echo Reply [RFC792]
3 Destination Unreachable [RFC792]
4 Source Quench [RFC792]
5 Redirect [RFC792]
8 Echo [RFC792]
11 Time Exceeded [RFC792]
We may want to filter ICMP messages type 4, these kind of messages are sent in case of congestion of the network.
# tcpdump -i eth1 'icmp[0] = 4'
If we want to find the ICMP echo replies only, having an ID of 500. By looking at the image with all the ICMP packet description
we see the ICMP echo reply have the ID spread across the 5th and 6th byte. For some reason, we have to filter out with the value in hex.
# tcpdump -i eth0 '(icmp[0] = 0) and (icmp[4:2] = 0x1f4)'
TOS (Dec) TOS (Hex) TOS (Bin) TOS Precedence (Bin) TOS Precedence (Dec) TOS Precedence Name TOS Delay flag TOS Throughput flag TOS Reliability flag DSCP (Bin) DSCP (Hex) DSCP (Dec) DSCP/PHB Class
0 0x00 00000000 000 0 Routine 0 0 0 000000 0x00 0 none
32 0x20 00100000 001 1 Priority 0 0 0 001000 0x08 8 cs1
40 0x28 00101000 001 1 Priority 0 1 0 001010 0x0A 10 af11
48 0x30 00110000 001 1 Priority 1 0 0 001100 0x0C 12 af12
56 0x38 00111000 001 1 Priority 1 1 0 001110 0x0E 14 af13
64 0x40 01000000 010 2 Immediate 0 0 0 010000 0x10 16 cs2
72 0x48 01001000 010 2 Immediate 0 1 0 010010 0x12 18 af21
80 0x50 01010000 010 2 Immediate 1 0 0 010100 0x14 20 af22
88 0x58 01011000 010 2 Immediate 1 1 0 010110 0x16 22 af23
96 0x60 01100000 011 3 Flash 0 0 0 011000 0x18 24 cs3
104 0x68 01101000 011 3 Flash 0 1 0 011010 0x1A 26 af31
112 0x70 01110000 011 3 Flash 1 0 0 011100 0x1C 28 af32
120 0x78 01111000 011 3 Flash 1 1 0 011110 0x1E 30 af33
128 0x80 10000000 100 4 FlashOverride 0 0 0 100000 0x20 32 cs4
136 0x88 10001000 100 4 FlashOverride 0 1 0 100010 0x22 34 af41
144 0x90 10010000 100 4 FlashOverride 1 0 0 100100 0x24 36 af42
152 0x98 10011000 100 4 FlashOverride 1 1 0 100110 0x26 38 af43
160 0xA0 10100000 101 5 Critical 0 0 0 101000 0x28 40 cs5
184 0xB8 10111000 101 5 Critical 1 1 0 101110 0x2E 46 ef
192 0xC0 11000000 110 6 InterNetworkControl 0 0 0 110000 0x30 48 cs6
224 0xE0 11100000 111 7 NetworkControl 0 0 0 111000 0x38 56 cs7
ip IP
arp arp
tcp tcp
udp udp
icmp icmp
ip multicast IP Multicast
ether multicast Ethernet Multicast
IP Filters
ip[0] & 0x0f low nibble: header length in 4octet words. should be 5
ip[1] type of service/QoS/DiffServ
ip[2:2] total length of datagram in octets
ip[4:2] IP ID number
ip[6] & 0x80 reserved bit (possibly used for ECN)
ip[6] & 0x40 DF bit
ip[6] & 0x20 MF bit
ip[6:2] & 0x1fff fragment offset (number of 8octet blocks)
ip[8] ttl
ip[9] protocol
ip[10:2] header checksum
ip[12:4] source IP
ip[16:4] destination IP
Samples
(ip[12:4] = ip[16:4]) Src IP = Dest IP (land attack)
ip[0] & 0xf0 high nibble: IP version. almost always 4
(ip[0] & 0xf0 != 0x40) IP versions !=4
(ip[0:1] & 0x0f > 5) IP with options set
(ip[19] = 0xff) Broadcasts to x.x.x.255
(ip[19] = 0x00) Broadcasts to x.x.x.0
(ip and ip[1] & 0xfc == 0xb8) search for EF in DSCP
(ip and ip[1] & 0xfc == 0x28) search for AF11 in DSCP
(ip and ip[1] & 0xfc != 0x00) search for DCSP Packets != 0
(ip[6] & 0x20 != 0) && (ip[6:2] & 0x1fff = 0) initial fragments
(ip[6] & 0x20 != 0) && (ip[6:2] & 0x1fff != 0) intervening fragments
(ip[6] & 0x20 = 0) && (ip[6:2] & 0x1fff != 0) terminal fragments
(ip[0] & 0x0f) != 5 has ip options (or is truncated, or is just some sort of freak...)
ip[8] < 5 short TTL value
ip[6] = 32 MF set
iip[2:2] > 999 IP Packet greater then 999
ICMP Filters
icmp[0] type
icmp[1] code
icmp[2:2] checksum
Samples
icmp[0]=0x# all Packets with ICMP Type
icmp[0]=0x# and icmp[1]=0x# all Packets with ICMP Type X and Code = Y
icmp[0]=8 ICMP Request Messages
icmp[8]=0 ICMP Request Replay
icmp[0]=0x11 ICMP Address Mask Request
icmp[0]=0x12 ICMP Address Mask Replay
icmp[0]=11 and icmp[1]=0 ICMP Time Exeedet
icmp[0]=3 and icmp[1]=4 ICMP Time Exeedet
icmp[0]=8 and ip[2:2] > 64 Large ICMP Packets
TCP Filters
tcp[0:2] source port
tcp[2:2] destination port
tcp[4:4] sequence number
tcp[8:4] ack number
tcp[12] header length
tcp[13] tcp flags
---- --S- 0000 0010 = 0x02 normal syn
---A --S- 0001 0010 = 0x12 normal syn-ack
---A ---- 0001 0000 = 0x10 normal ack
--UA P--- 0011 1000 = 0x38 psh-urg-ack. interactive stuff like ssh
---A -R-- 0001 0100 = 0x14 rst-ack. it happens.
---- --SF 0000 0011 = 0x03 syn-fin scan
--U- P--F 0010 1001 = 0x29 urg-psh-fin. nmap fingerprint packet
-Y-- ---- 0100 0000 = 0x40 anything >= 0x40 has a reserved bit set
XY-- ---- 1100 0000 = 0xC0 both reserved bits set
XYUA PRSF 1111 1111 = 0xFF FULL_XMAS scan
tcp[14:2] window size
tcp[16:2] checksumt
tcp[18:2] urgent pointer
Samples
tcp[13] = 0x02 is SYN. nothing else.
(tcp[13] & 0x02) != 0 contains SYN. we don't care what else...
(tcp[13] & 0x03) = 3 is some kind of SYN-FIN. realy Bad
winnuke (not tested)
tcp[20:4] = 0x47455420 GET in request
UDP Filters
udp[0:2] source port
udp[2:2] destination port
udp[4:2] datagram length
udp[6:2] UDP checksum
protocols
ip[9] == 8 EGP
ip[9] == 9 IGP
ip[9] == 88 EIRGP
ip[9] == 50 ESP
ip[9] == 51 AH
ip[9] == 89 OSPF
ip[9] == 124 ISIS
other, see /etc/protocols
Routing Protocols
(udp and port 520) or (host 224.0.0.9) RIP 1 + 2
tcp and port 179 BGP
ip[9] == 8 EGP
ip[9] == 9 IGP
ip[9] == 88 EIRGP
ip[9] == 89 OSPF
ip[9] == 124 ISIS
ether Filters
ether[20:2] == 0x2000 CDP pakets
ether[12:2] == 0x0806 ARP pakets
IPv6
ip6 filters native IPv6 traffic (including ICMPv6)
icmp6 filters native ICMPv6 traffic
proto ipv6 filters tunneled IPv6-in-IPv4 traffic
TCP
ip6 and (ip6[6] == 0x06) IPv6 TCP
ip6 and (ip6[6] == 0x06) and (ip6[53] == 0x02) IPv6 TCP Syn
ip6 and (ip6[6] == 0x06) and (ip6[53] == 0x10) IPv6 TCP ACK
ip6 and (ip6[6] == 0x06) and (ip6[53] == 0x12) IPv6 TCP Syn/ACK
UDP
ip6 and (ip6[6] == 0x11) IPv6 TCP
ICMP
(ip6[6] == 0x3a) ICMP v6
(ip6[6] == 0x3a) and (ip6[40] == 0x01) ipv6 and type 1 Dest Unreachable
(ip6[6] == 0x3a) and (ip6[40] == 0x02) ipv6 and type 2 Packet too big
(ip6[6] == 0x3a) and (ip6[40] == 0x03) ipv6 and type 3 Time Exeedet
(ip6[6] == 0x3a) and (ip6[40] == 0x04) ipv6 and type 4 Parameter Problem
(ip6[6] == 0x3a) and (ip6[40] == 0x80) ipv6 and type 128 Echo Request
(ip6[6] == 0x3a) and (ip6[40] == 0x81) ipv6 and type 129 Echo Reply
(ip6[6] == 0x3a) and (ip6[40] == 0x86) ipv6 and type 133 Router Solicitation
(ip6[6] == 0x3a) and (ip6[40] == 0x87) ipv6 and type 134 Router Advertisement
(ip6[6] == 0x3a) and (ip6[40] == 0x88) ipv6 and type 135 Neighbor Solicitation
(ip6[6] == 0x3a) and (ip6[40] == 0x89) ipv6 and type 136 Neighbor Advertisement
Basic syntax :
==============
Filtering hosts :
-----------------
- Match any traffic involving 192.168.1.1 as destination or source
# tcpdump -i eth1 host 192.168.1.1
- As soure only
# tcpdump -i eth1 src host 192.168.1.1
- As destination only
# tcpdump -i eth1 dst host 192.168.1.1
Filtering ports :
-----------------
- Match any traffic involving port 25 as source or destination
# tcpdump -i eth1 port 25
- Source
# tcpdump -i eth1 src port 25
- Destination
# tcpdump -i eth1 dst port 25
Network filtering :
-------------------
# tcpdump -i eth1 net 192.168
# tcpdump -i eth1 src net 192.168
# tcpdump -i eth1 dst net 192.168
Protocol filtering :
--------------------
# tcpdump -i eth1 arp
# tcpdump -i eth1 ip
# tcpdump -i eth1 tcp
# tcpdump -i eth1 udp
# tcpdump -i eth1 icmp
Let's combine expressions :
---------------------------
Negation : ! or "not" (without the quotes)
Concatanate : && or "and"
Alternate : || or "or"
- This rule will match any TCP traffic on port 80 (web) with 192.168.1.254 or 192.168.1.200 as destination host
# tcpdump -i eth1 '((tcp) and (port 80) and ((dst host 192.168.1.254) or (dst host 192.168.1.200)))'
- Will match any ICMP traffic involving the destination with physical/MAC address 00:01:02:03:04:05
# tcpdump -i eth1 '((icmp) and ((ether dst host 00:01:02:03:04:05)))'
- Will match any traffic for the destination network 192.168 except destination host 192.168.1.200
# tcpdump -i eth1 '((tcp) and ((dst net 192.168) and (not dst host 192.168.1.200)))'
Advanced header filtering :
===========================
Before we continue, we need to know how to filter out info from headers
proto[x:y] : will start filtering from byte x for y bytes. ip[2:2] would filter bytes 3 and 4 (first byte begins by 0)
proto[x:y] & z = 0 : will match bits set to 0 when applying mask z to proto[x:y]
proto[x:y] & z !=0 : some bits are set when applying mask z to proto[x:y]
proto[x:y] & z = z : every bits are set to z when applying mask z to proto[x:y]
proto[x:y] = z : p[x:y] has exactly the bits set to z
Operators : >, <, >=, <=, =, !=
This may not be clear in the first place but you'll find examples below involving these.
Of course, it is important to know what the protocol headers look like before diving into more advanced filters.
IP header
---------
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding | <-- optional
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| DATA ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
I'll consider we are only working with the IPv4 protocol suite for these examples.
In an ideal world, every field would fit inside one byte. This is not the case, of course.
Are IP options set ?
--------------------
Let's say we want to know if the IP header has options set. We can't just try to filter out the 21st byte
because if no options are set, data start at the 21st byte. We know a "normal" header is usually 20 bytes
(160 bits) long. With options set, the header is longer than that. The IP header has the header
length field which we will filter here to know if the header is longer than 20 bytes.
+-+-+-+-+-+-+-+-+
|Version| IHL |
+-+-+-+-+-+-+-+-+
Usually the first byte has a value of 01000101 in binary.
Anyhow, we need to divide the first byte in half...
0100 = 4 in decimal. This is the IP version.
0101 = 5 in decimal. This is the number of blocks of 32 bits in the headers. 5 x 32 bits = 160 bits or 20 bytes.
The second half of the first byte would be bigger than 5 if the header had IP options set.
We have two ways of dealing with that kind of filters.
1. Either try to match a value bigger than 01000101. This would trigger matches for IPv4 traffic with IP options set,
but ALSO any IPv6 traffic !
In decimal 01000101 equals 69.
Let's recap how to calculate in decimal.
0 : 0 \
1 : 2^6 = 64 \ First field (IP version)
0 : 0 /
0 : 0 /
-
0 : 0 \
1 : 2^2 = 4 \ Second field (Header length)
0 : 0 /
1 : 2^0 = 1 /
64 + 4 + 1 = 69
The first field in the IP header would usually have a decimal value of 69.
If we had IP options set, we would probably have 01000110 (IPv4 = 4 + header = 6), which in decimal equals 70.
This rule should do the job :
# tcpdump -i eth1 'ip[0] > 69'
Somehow, the proper way is to mask the first half/field of the first byte, because as mentionned earlier,
this filter would match any IPv6 traffic.
2. The proper way : masking the first half of the byte
0100 0101 : 1st byte originally
0000 1111 : mask (0x0f in hex or 15 in decimal). 0 will mask the values while 1 will keep the values intact.
=========
0000 0101 : final result
The correct filter :
# tcpdump -i eth1 'ip[0] & 15 > 5'
or
# tcpdump -i eth1 'ip[0] & 0x0f > 5'
DF bit (don't fragment) set ?
-----------------------------
Let's now trying to know if we have fragmentation occuring, which is not desirable. Fragmentation occurs
when a the MTU of the sender is bigger than the path MTU on the path to destination.
Fragmentation info can be found in the 7th and 8th byte of the IP header.
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Bit 0: reserved, must be zero
Bit 1: (DF) 0 = May Fragment, 1 = Don't Fragment.
Bit 2: (MF) 0 = Last Fragment, 1 = More Fragments.
The fragment offset field is only used when fragmentation occurs.
If we want to match the DF bit (don't fragment bit, to avoid IP fragmentation) :
The 7th byte would have a value of :
01000000 or 64 in decimal
# tcpdump -i eth1 'ip[6] = 64'
Matching fragmentation ?
------------------------
- Matching MF (more fragment set) ? This would match the fragmented datagrams but wouldn't match the last
fragment (which has the 2nd bit set to 0).
# tcpdump -i eth1 'ip[6] = 32'
The last fragment have the first 3 bits set to 0... but has data in the fragment offset field.
- Matching the fragments and the last fragments
# tcpdump -i eth1 '((ip[6:2] > 0) and (not ip[6] = 64))'
A bit of explanations :
"ip[6:2] > 0" would return anything with a value of at least 1
We don't want datagrams with the DF bit set though.. the reason of the "not ip[6] = 64"
If you want to test fragmentation use something like :
ping -M want -s 3000 192.168.1.1
Matching datagrams with low TTL
-------------------------------
The TTL field is located in the 9th byte and fits perfectly into 1 byte.
The maximum decimal value of the TTL field is thus 255 (11111111 in binary).
This can be verified :
$ ping -M want -s 3000 -t 256 192.168.1.200
ping: ttl 256 out of range
+-+-+-+-+-+-+-+-+
| Time to Live |
+-+-+-+-+-+-+-+-+
We can try to find if someone on our network is using traceroute by using something like this on the gateway :
# tcpdump -i eth1 'ip[8] < 5'
Matching packets longer than X bytes
------------------------------------
Where X is 600 bytes
# tcpdump -i eth1 'ip[2:2] > 600'
More IP filtering
-----------------
We could imagine filtering source and destination addresses directly in decimal addressing.
We could also match the protocol by filtering the 10th byte.
It would be pointless anyhow, because tcpdump makes it already easy to filter out that kind of info.
TCP header
----------
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |C|E|U|A|P|R|S|F| |
| Offset| Res. |W|C|R|C|S|S|Y|I| Window |
| | |R|E|G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Matching any TCP traffic with a source port > 1024
# tcpdump -i eth1 'tcp[0:2] > 1024'
- Matching TCP traffic with particular flag combinations
The flags are defined in the 14th byte of the TCP header.
+-+-+-+-+-+-+-+-+
|C|E|U|A|P|R|S|F|
|W|C|R|C|S|S|Y|I|
|R|E|G|K|H|T|N|N|
+-+-+-+-+-+-+-+-+
In the TCP 3-way handshakes, the exchange between hosts goes like this :
1. Source sends SYN
2. Destination answers with SYN, ACK
3. Source sends ACK
- If we want to match packets with only the SYN flag set, the 14th byte would have a binary
value of 00000010 which equals 2 in decimal.
# tcpdump -i eth1 'tcp[13] = 2'
- Matching SYN, ACK (00010010 or 18 in decimal)
# tcpdump -i eth1 'tcp[13] = 18'
- Matching either SYN only or SYN-ACK datagrams
# tcpdump -i eth1 'tcp[13] & 2 = 2'
We used a mask here. It will returns anything with the ACK bit set (thus the SYN-ACK combination as well)
Let's assume the following examples (SYN-ACK)
00010010 : SYN-ACK packet
00000010 : mask (2 in decimal)
--------
00000010 : result (2 in decimal)
Every bits of the mask match !
- Matching PSH-ACK packets
# tcpdump -i eth1 'tcp[13] = 24'
- Matching any combination containing FIN (FIN usually always comes with an ACK so we either
need to use a mask or match the combination ACK-FIN)
# tcpdump -i eth1 'tcp[13] & 1 = 1'
- Matching RST flag
# tcpdump -i eth1 'tcp[13] & 4 = 4'
By looking at the TCP state machine diagram (http://www.wains.be/pub/networking/tcp_state_machine.jpg)
we can find the different flag combinations we may want to analyze.
Ideally, a socket in ACK_WAIT mode should not have to send a RST. It means the 3 way handshake has not completed.
We may want to analyze that kind of traffic.
Matching SMTP data :
--------------------
I will make a filter that will match any packet containing the "MAIL" command from SMTP exchanges.
I use something like http://www.easycalculation.com/ascii-hex.php to convert values from ASCII to hexadecimal.
"MAIL" in hex is 0x4d41494c
The rule would be :
# tcpdump -i eth1 '((port 25) and (tcp[20:4] = 0x4d41494c))'
It will check the bytes 21 to 24. "MAIL" is 4 bytes/32 bits long..
This rule would not match packets with IP options set.
This is an example of packet (a spam, of course) :
# tshark -V -i eth0 '((port 25) and (tcp[20:4] = 0x4d41494c))'
Capturing on eth0
Frame 1 (92 bytes on wire, 92 bytes captured)
Arrival Time: Sep 25, 2007 00:06:10.875424000
[Time delta from previous packet: 0.000000000 seconds]
[Time since reference or first frame: 0.000000000 seconds]
Frame Number: 1
Packet Length: 92 bytes
Capture Length: 92 bytes
[Frame is marked: False]
[Protocols in frame: eth:ip:tcp:smtp]
Ethernet II, Src: Cisco_X (00:11:5c:X), Dst: 3Com_X (00:04:75:X)
Destination: 3Com_X (00:04:75:X)
Address: 3Com_X (00:04:75:X)
.... ...0 .... .... .... .... = IG bit: Individual address (unicast)
.... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
Source: Cisco_X (00:11:5c:X)
Address: Cisco_X (00:11:5c:X)
.... ...0 .... .... .... .... = IG bit: Individual address (unicast)
.... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
Type: IP (0x0800)
Internet Protocol, Src: 62.163.X (62.163.X), Dst: 192.168.X (192.168.X)
Version: 4
Header length: 20 bytes
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
0000 00.. = Differentiated Services Codepoint: Default (0x00)
.... ..0. = ECN-Capable Transport (ECT): 0
.... ...0 = ECN-CE: 0
Total Length: 78
Identification: 0x4078 (16504)
Flags: 0x04 (Don't Fragment)
0... = Reserved bit: Not set
.1.. = Don't fragment: Set
..0. = More fragments: Not set
Fragment offset: 0
Time to live: 118
Protocol: TCP (0x06)
Header checksum: 0x08cb [correct]
[Good: True]
[Bad : False]
Source: 62.163.X (62.163.X)
Destination: 192.168.X (192.168.XX)
Transmission Control Protocol, Src Port: 4760 (4760), Dst Port: smtp (25), Seq: 0, Ack: 0, Len: 38
Source port: 4760 (4760)
Destination port: smtp (25)
Sequence number: 0 (relative sequence number)
[Next sequence number: 38 (relative sequence number)]
Acknowledgement number: 0 (relative ack number)
Header length: 20 bytes
Flags: 0x18 (PSH, ACK)
0... .... = Congestion Window Reduced (CWR): Not set
.0.. .... = ECN-Echo: Not set
..0. .... = Urgent: Not set
...1 .... = Acknowledgment: Set
.... 1... = Push: Set
.... .0.. = Reset: Not set
.... ..0. = Syn: Not set
.... ...0 = Fin: Not set
Window size: 17375
Checksum: 0x6320 [correct]
[Good Checksum: True]
[Bad Checksum: False]
Simple Mail Transfer Protocol
Command: MAIL FROM:
Command: MAIL
Request parameter: FROM:
Matching HTTP data :
--------------------
Let's make a filter that will find any packets containing GET requests
The HTTP request will begin by :
GET / HTTP/1.1\r\n (16 bytes counting the carriage return but not the backslashes !)
If no IP options are set.. the GET command will use the byte 20, 21 and 22
Tcpdump is only able to match data size of either 1, 2 or 4 bytes, we will take the following ASCII
character following the GET command (a space)
"GET " in hex : 47455420
# tcpdump -i eth1 'tcp[20:4] = 0x47455420'
Matching other interesting TCP things :
---------------------------------------
SSH connection (on any port) :
We will be looking for the reply given by the SSH server.
OpenSSH usually replies with something like "SSH-2.0-OpenSSH_3.6.1p2".
The first 4 bytes (SSH-) have an hex value of 0x5353482D.
# tcpdump -i eth1 'tcp[(tcp[12]>>2):4] = 0x5353482D'
If we want to find any connection made to older version of OpenSSH (version 1, which are insecure and subject to MITM attacks) :
The reply from the server would be something like "SSH-1.99.."
# tcpdump -i eth1 '(tcp[(tcp[12]>>2):4] = 0x5353482D) and (tcp[((tcp[12]>>2)+4):2] = 0x312E)'
UDP header
----------
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| Source | Destination |
| Port | Port |
+--------+--------+--------+--------+
| | |
| Length | Checksum |
+--------+--------+--------+--------+
| |
| DATA ... |
+-----------------------------------+
Nothing really interesting here.
If we want to filter ports we would use something like :
# tcpdump -i eth1 udp dst port 53
ICMP header
-----------
See different ICMP messages :
http://img292.imageshack.us/my.php?image=icmpmm6.gif
We will usually filter the type (1 byte) and code (1 byte) of the ICMP messages.
Here are common ICMP types :
0 Echo Reply [RFC792]
3 Destination Unreachable [RFC792]
4 Source Quench [RFC792]
5 Redirect [RFC792]
8 Echo [RFC792]
11 Time Exceeded [RFC792]
We may want to filter ICMP messages type 4, these kind of messages are sent in case of congestion of the network.
# tcpdump -i eth1 'icmp[0] = 4'
If we want to find the ICMP echo replies only, having an ID of 500. By looking at the image with all the ICMP packet description
we see the ICMP echo reply have the ID spread across the 5th and 6th byte. For some reason, we have to filter out with the value in hex.
# tcpdump -i eth0 '(icmp[0] = 0) and (icmp[4:2] = 0x1f4)'
TOS (Dec) TOS (Hex) TOS (Bin) TOS Precedence (Bin) TOS Precedence (Dec) TOS Precedence Name TOS Delay flag TOS Throughput flag TOS Reliability flag DSCP (Bin) DSCP (Hex) DSCP (Dec) DSCP/PHB Class
0 0x00 00000000 000 0 Routine 0 0 0 000000 0x00 0 none
32 0x20 00100000 001 1 Priority 0 0 0 001000 0x08 8 cs1
40 0x28 00101000 001 1 Priority 0 1 0 001010 0x0A 10 af11
48 0x30 00110000 001 1 Priority 1 0 0 001100 0x0C 12 af12
56 0x38 00111000 001 1 Priority 1 1 0 001110 0x0E 14 af13
64 0x40 01000000 010 2 Immediate 0 0 0 010000 0x10 16 cs2
72 0x48 01001000 010 2 Immediate 0 1 0 010010 0x12 18 af21
80 0x50 01010000 010 2 Immediate 1 0 0 010100 0x14 20 af22
88 0x58 01011000 010 2 Immediate 1 1 0 010110 0x16 22 af23
96 0x60 01100000 011 3 Flash 0 0 0 011000 0x18 24 cs3
104 0x68 01101000 011 3 Flash 0 1 0 011010 0x1A 26 af31
112 0x70 01110000 011 3 Flash 1 0 0 011100 0x1C 28 af32
120 0x78 01111000 011 3 Flash 1 1 0 011110 0x1E 30 af33
128 0x80 10000000 100 4 FlashOverride 0 0 0 100000 0x20 32 cs4
136 0x88 10001000 100 4 FlashOverride 0 1 0 100010 0x22 34 af41
144 0x90 10010000 100 4 FlashOverride 1 0 0 100100 0x24 36 af42
152 0x98 10011000 100 4 FlashOverride 1 1 0 100110 0x26 38 af43
160 0xA0 10100000 101 5 Critical 0 0 0 101000 0x28 40 cs5
184 0xB8 10111000 101 5 Critical 1 1 0 101110 0x2E 46 ef
192 0xC0 11000000 110 6 InterNetworkControl 0 0 0 110000 0x30 48 cs6
224 0xE0 11100000 111 7 NetworkControl 0 0 0 111000 0x38 56 cs7
miércoles, 30 de junio de 2010
Backup and restore CACTI
Subject: Migracion OLD-CACTI > New-Cacti
Posted on: enero 28 2009 @ 08:27
By: Cachorroyayo
Content:
Hola Foro....
Como estamos siempre para darnos la mano esta ocacion quiero dejar un grano de arena para los que quizas en algun momento puedan necesitar de esto.
Tengo un servidor cactihttp://www.cacti.net/, el cual me pidieron hacer un backUp y levantarlo en un nuevo server. Bueno yo lo instale en FreeBSD que es lo que usamos aca en el ISP pero creo que no estaria de mas el aporte y ojala les sea de Utilidad.
Ahi les va....
Backup de Cacti y pasarlo a un nuevo servidor sin perder nada de data Smile
Necesitamos instalar los siguientes ports en el nuevo servidor.
/usr/ports/www/apache22
/usr/ports/databases/mysql50-server
/usr/ports/lang/php5
/usr/ports/lang/php5-extensions
/usr/ports/net-mgmt/net-snmp4
/usr/ports/databases/rrdtool
usr/ports/net-mgmt/cacti
Con Apache y MySQL no hay problema pero cuando vas a instalar php5
#cd /usr/ports/lang/php5
# make install clean
Posiblemente al final de la instalacion te de un mensaje de error que tiene que ver con curl (ftp-curl y php5-curl)
cuando trates de instalar el curl por las buenas te dira que CARES Y IPV6 no pueden estar juntos,
Ahora estas son opciones de Curl un port de prerequisito de php5 para salir de esta, editamos el Makefile de curl y
luego lo trabajamos normal para que no de problemas al instalar el php5
# vi /usr/ports/ftp/curl/Makefile
#.if defined(WITH_CARES) && defined(WITH_IPV6)
#IGNORE= does not support both c-ares and IPv6 - disable one of them
#.endif
# make install clean
luego instalas normal
# cd /usr/ports/lang/php5
# cd /usr/ports/lang/php5-extensions
#cd /usr/ports/net-mgmt/net-snmp4
cacti usa net-snmp4 asi que si instalamos net-snmp53 habran conflictos es mejor hacerlo a la primera y no instalar y luego
desinstalar el net-snmp 2 veces hasta que te des cuenta del error.
#cd /usr/ports/databases/rrdtool
#cd usr/ports/net-mgmt/cacti
Ya con los ports instalados procedemos a configurar lo que necesitamos.
Agregamos a /etc/rc.conf
apache22_enable="YES"
mysql_enable="YES"
snmpd_enable="YES"
# /usr/local/etc/rc.d/apache22 start
# /usr/local/etc/rc.d/mysql-server start
# /usr/local/etc/rc.d/snmpd start
APACHE
Modificamos el httpd.conf con unicamente lo siguiente
LoadModule php5_module libexec/apache22/libphp5.so
DocumentRoot "/usr/local/share/cacti"
Alias /cacti /usr/local/share/cacti
Order allow,deny
Allow from all
DirectoryIndex index.php index.html
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
#/usr/local/etc/rc.d/apache22 restart
MYSQL
Seteamos el password del Root
# mysqladmin -u root password 'N3wR0ot.P4s5w0rd'
Creamos la Base de Datos para el Cacti
#mysql -u root pN3wR0ot.P4s5w0rd
MYSQL> CREATE DATABASE cacti;
CACTI
Para que cacti pueda usar la Base de datos que hemos creado en MySQL necesitamos darle permisos en el siguiente archivo
dejando todo tal como se ve:
#vi /usr/local/share/cacti/include/config.php
$database_default = "cacti";
$database_hostname = "localhost";
$database_username = "cacti";
$database_password = "cacti";
Tenemos que darle permisos a Cacti para que pueda hacer el poller y generar las graficas y el chequeo SNMP
#cd /usr/local/share/cacti
#chown -R cacti:www rra/ log/
Y le damos el siguiente script de cron para que haga el poller cada 5 minutos
# crontab -e -u cacti
*/5 * * * * /usr/local/bin/php /usr/local/share/cacti/poller.php> /dev/null
Esto es lo minimo para nuestra configuracion de CACTI, pero como nosotros queremos migrar todos los cientos y por que no miles de archivos
rrd que se han creado en nuestro antguo servidor al nuevo; tenemos que hacer lo siguiente:
OLDCACTI
Dumpeamos la Base de Datos de Cacti
#mysqldump -u root -p cacti > cacti-dump.sql
La debemos de copiar al nuevo servidor
#scp cacti-dump.sql user@newcacti:/usr/local/share/cacti
Luego tenemos que pasar todos los archivos rrd al nuevo servidor. pero primero tenemos que pasarlos a plantilla xml de la siguiente manera.
# cd /usr/share/cacti/rra/# ls -1 *.rrd | awk '{print "rrdtool dump "$1" > "$1".xml"}' | sh -x
Los pasamos al nuevo servidor
scp *.xml user@newcacti:/usr/share/cacti/rra/
NEWCACTI
Eliminamos cualquier archivo rrd que se pueda haber creado
# rm -Rf *.rrd
Comvertimos cada xml en un rrd:
# cd /usr/share/cacti/rra/# ls -1 *.rrd.xml | sed 's/\.xml//' | awk '{print "rrdtool restore "$1".xml "$1}' | sh -x
Eliminamos todos los xml y le damos permiso a los usuarios que corresponde
# rm *.xml
# chown -R cacti:www *
Ahora tenemos que reemplazar la vieja base de datos con la nueva que acabamos de pasar por scp
# mysql -u root -p <> mysql -u root -p
MYSQL> GRANT ALL ON cacti.* TO cactiuser@localhost IDENTIFIED BY 'cacti';
MYSQL> FLUSH PRIVILEGES;
Posted on: enero 28 2009 @ 08:27
By: Cachorroyayo
Content:
Hola Foro....
Como estamos siempre para darnos la mano esta ocacion quiero dejar un grano de arena para los que quizas en algun momento puedan necesitar de esto.
Tengo un servidor cactihttp://www.cacti.net/, el cual me pidieron hacer un backUp y levantarlo en un nuevo server. Bueno yo lo instale en FreeBSD que es lo que usamos aca en el ISP pero creo que no estaria de mas el aporte y ojala les sea de Utilidad.
Ahi les va....
Backup de Cacti y pasarlo a un nuevo servidor sin perder nada de data Smile
Necesitamos instalar los siguientes ports en el nuevo servidor.
/usr/ports/www/apache22
/usr/ports/databases/mysql50-server
/usr/ports/lang/php5
/usr/ports/lang/php5-extensions
/usr/ports/net-mgmt/net-snmp4
/usr/ports/databases/rrdtool
usr/ports/net-mgmt/cacti
Con Apache y MySQL no hay problema pero cuando vas a instalar php5
#cd /usr/ports/lang/php5
# make install clean
Posiblemente al final de la instalacion te de un mensaje de error que tiene que ver con curl (ftp-curl y php5-curl)
cuando trates de instalar el curl por las buenas te dira que CARES Y IPV6 no pueden estar juntos,
Ahora estas son opciones de Curl un port de prerequisito de php5 para salir de esta, editamos el Makefile de curl y
luego lo trabajamos normal para que no de problemas al instalar el php5
# vi /usr/ports/ftp/curl/Makefile
#.if defined(WITH_CARES) && defined(WITH_IPV6)
#IGNORE= does not support both c-ares and IPv6 - disable one of them
#.endif
# make install clean
luego instalas normal
# cd /usr/ports/lang/php5
# cd /usr/ports/lang/php5-extensions
#cd /usr/ports/net-mgmt/net-snmp4
cacti usa net-snmp4 asi que si instalamos net-snmp53 habran conflictos es mejor hacerlo a la primera y no instalar y luego
desinstalar el net-snmp 2 veces hasta que te des cuenta del error.
#cd /usr/ports/databases/rrdtool
#cd usr/ports/net-mgmt/cacti
Ya con los ports instalados procedemos a configurar lo que necesitamos.
Agregamos a /etc/rc.conf
apache22_enable="YES"
mysql_enable="YES"
snmpd_enable="YES"
# /usr/local/etc/rc.d/apache22 start
# /usr/local/etc/rc.d/mysql-server start
# /usr/local/etc/rc.d/snmpd start
APACHE
Modificamos el httpd.conf con unicamente lo siguiente
LoadModule php5_module libexec/apache22/libphp5.so
DocumentRoot "/usr/local/share/cacti"
Alias /cacti /usr/local/share/cacti
Order allow,deny
Allow from all
DirectoryIndex index.php index.html
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
#/usr/local/etc/rc.d/apache22 restart
MYSQL
Seteamos el password del Root
# mysqladmin -u root password 'N3wR0ot.P4s5w0rd'
Creamos la Base de Datos para el Cacti
#mysql -u root pN3wR0ot.P4s5w0rd
MYSQL> CREATE DATABASE cacti;
CACTI
Para que cacti pueda usar la Base de datos que hemos creado en MySQL necesitamos darle permisos en el siguiente archivo
dejando todo tal como se ve:
#vi /usr/local/share/cacti/include/config.php
$database_default = "cacti";
$database_hostname = "localhost";
$database_username = "cacti";
$database_password = "cacti";
Tenemos que darle permisos a Cacti para que pueda hacer el poller y generar las graficas y el chequeo SNMP
#cd /usr/local/share/cacti
#chown -R cacti:www rra/ log/
Y le damos el siguiente script de cron para que haga el poller cada 5 minutos
# crontab -e -u cacti
*/5 * * * * /usr/local/bin/php /usr/local/share/cacti/poller.php> /dev/null
Esto es lo minimo para nuestra configuracion de CACTI, pero como nosotros queremos migrar todos los cientos y por que no miles de archivos
rrd que se han creado en nuestro antguo servidor al nuevo; tenemos que hacer lo siguiente:
OLDCACTI
Dumpeamos la Base de Datos de Cacti
#mysqldump -u root -p cacti > cacti-dump.sql
La debemos de copiar al nuevo servidor
#scp cacti-dump.sql user@newcacti:/usr/local/share/cacti
Luego tenemos que pasar todos los archivos rrd al nuevo servidor. pero primero tenemos que pasarlos a plantilla xml de la siguiente manera.
# cd /usr/share/cacti/rra/# ls -1 *.rrd | awk '{print "rrdtool dump "$1" > "$1".xml"}' | sh -x
Los pasamos al nuevo servidor
scp *.xml user@newcacti:/usr/share/cacti/rra/
NEWCACTI
Eliminamos cualquier archivo rrd que se pueda haber creado
# rm -Rf *.rrd
Comvertimos cada xml en un rrd:
# cd /usr/share/cacti/rra/# ls -1 *.rrd.xml | sed 's/\.xml//' | awk '{print "rrdtool restore "$1".xml "$1}' | sh -x
Eliminamos todos los xml y le damos permiso a los usuarios que corresponde
# rm *.xml
# chown -R cacti:www *
Ahora tenemos que reemplazar la vieja base de datos con la nueva que acabamos de pasar por scp
# mysql -u root -p <> mysql -u root -p
MYSQL> GRANT ALL ON cacti.* TO cactiuser@localhost IDENTIFIED BY 'cacti';
MYSQL> FLUSH PRIVILEGES;
martes, 29 de junio de 2010
Backup Linux Ubuntu - RSYNC
RSYNC COPIA LOCAL
rsync -altgvb /var/data/ /home/user/backup
RSYNC SSH - COPIA A UN SERVER.
rsync -e ssh -altgvb /data/ root@192.168.0.1:/home/user/backup
- Hasta aqui todo esta bien, pero si necesitamos hacer esto automaticamente cada hora mediante cron tenemos que lograr que ssh no nos pida contraseña. Para lograrlo realizamos el siguiente procedimiento:
Creamos una llave publica y una llave privada:
ssh-keygen -tdsa
Presionando solo enter en todas las preguntas que el comando anterior requiere vamos a tener nuestra llave publica en /home/usuario/.ssh/id_dsa.pub. Copiamos esta llave al servidor 192.168.0.1:
cd /home/usuario/.ssh/
cat id_dsa.pub | ssh bot@192.168.1.4 "cat - >> /home/bot/.ssh/authorized_keys"
Probamos que todo funcione haciendo:
ssh -l bot 192.168.1.4
Estas son las opciones de Rsync para entender mejor los comandos de arriba.
n no: no transferir solo mostrar lo que hay que hacer
# -a modo archivo (= -rlptDg)
# -r recursivo
# -l preservar soft links
# -p preservar permisos
# -t preservar fecha
# -D preservar dispositivos (solo root)
# -g preservar grupo
# -v modo verboso (-vv mas verboso)
# -z comprimir (si lo admite el servidor)
# -C ignorar archivos como lo hace CVS
# -u update: mantiene archivo destino si existe y es posterior
# -b backup: renombrar archivos destino preexistentes a extensión ~
# --stats imprimir estadisticas al final (solo si se ha puesto también -v)
# --delete borrar archivos en destino si no existen
# -R path relativos (crear rutas completas en el destino)
./rsync.sh install [push | pull] [local_dir] [remote_user] [remote_host] [remote_dir] [remote_ssh_port]
./rsync.sh install pull /home/brett/ brett 192.168.1.2 /home/brett 2222
./rsync.sh run [push | pull] localhost:'/home/paul /media/sdb1/music' [remote_user] [remote_host] [remote_dir] [remote_ssh_port]
The ssh-copy-id command is useful for copying the public key.
ssh-copy-id -i user@host
CLI (Command Line)
rsnapshot: a filesystem snapshot utility for making backups of local and remote systems. The disk space required is just a little more than the space of one full backup, plus incrementals. (My program does not use incrementals).
Code:
sudo aptitude install rsnapshot
Vocabulary
* ssh: a network protocol that allows data to be exchanged using a secure channel (encryption) between two computers
* rsync: a software application for Linux which synchronizes files and directories from one location to another using minimal bandwidth (only transfers files (or parts of files) that don't exist)
* mirror: an exact copy of a data set
* push: to send (or give) data from one computer to another
* pull: to receive (or ask) for data from one computer to another
Let's get started
It has several flags and options, but some are hard-coded, so you may have to edit the script by hand.
Options
General usage:
Quote:
./rsync.sh ['uninstall' | 'install' | 'run'] ['push' | 'pull'] [local_dir] [remote_user] [remote_host] [remote_dir] [remote_ssh_port]
Note: '[remote_ssh_port]' is usually 22 unless you change it from the default. If you don't know how to change the ssh port, its more than likely 22.
install
Use this option if you want to setup an automated, nightly backup between one computer and another.
Arguments:
Quote:
./rsync.sh install [push | pull] [local_dir] [remote_user] [remote_host] [remote_dir] [remote_ssh_port]
Example:
Quote:
./rsync.sh install pull /home/brett/ brett 192.168.1.2 /home/brett 2222
* Creates the following directories: $HOME/bin, $HOME/cron, $HOME/logs
* Creates 4096-bit RSA encryption key (illegal in the USA I think)
* Installs file to directories above
uninstall
Use this option if you want to remove a previously installed setup.
Arguments:
Quote:
./rsync.sh uninstall [remote_user] [remote_host]
Example:
Quote:
./rsync.sh uninstall brett 192.168.1.2
* Removes cron-job
* Removes RSA key
run
Use this option if you want to run the program without installing anything. Good to use as a test and on a single-needs basis.
Arguments:
Quote:
./rsync.sh run [push | pull] [local_dir] [remote_user] [remote_host] [remote_dir] [remote_ssh_port]
Example:
Quote:
./rsync.sh run pull /home/brett/ brett 192.168.1.2 /home/brett 2222
* Runs rsync with your parameters
That turns out to be really easy. If you’ve got ssh, then you’ve probably got ssh-keygen, which exists for the sole purpose of generating public and private keys, which when created without a passphrase can be used for password-free logins. So I ran ssh-keygen to generate a 2048 bit RSA key without a passphrase (aka a passphraseless key). I could also have generated a 1024 bit DSA key. I’m not sure I understand the difference. I’m not sure it matters.
ssh-keygen -b 2048
Inside ~/.ssh, ssh-keygen created two standard files, id_rsa and id_rsa.pub, the private and public keys respectively. The next and final step is to copy and “install” the public key on my backup server (192.168.0.100).
ssh-copy-id -i ~/.ssh/id_rsa.pub jwatt@192.168.0.100
ssh-copy-id uses ssh to copy the public key to the remote server and appends it to the ~/.ssh/authorized_keys file. Of course I didn’t know about ssh-copy-id when I started, so I just scp-ed the file over and pasted the public key into the authorized_keys file.
At which point I could use ssh to login without a password! ssh knows to automatically check for the existence of the id_rsa private key and try logging in with that.
ssh 192.168.0.100
Hot damn! That alone makes me want to start distributing my public key around to every server I access regularly. Of course the other benefit (and the whole point of this post!) is that now I’ll also be able to cron an rsync backup without requiring a password.
My ideal backup is a relatively current mirror of my home directory. I’m not looking for modified file snapshots or entire bootable filesystem images, I just want to know that if my hard drive crashes, most of my data (especially the photos) is recoverable. To that end, my rsync needs are relatively simple, though it took some tweaking to get to this point:
rsync -aze ssh --delete --exclude=".*/" /home/jwatt/ jwatt@192.168.0.100:/home/jwatt/backup/x23/
The -a option means archive files—it’s really an alias for a lot of other options having to do with maintaining permissions and timestamps, etc. The -z option uses compression when transferring files. The -e ssh option tunnels the file transfer over an encrypted ssh connection. The --delete option deletes any destination files that have been deleted from the source. The --exclude=".*/" option skips hidden files and directories. Finally the last two parts are the source (in this case everything under my home directory) and the destination I’ve already set up on my backup server.
And that’s it. I added it to my cron to run daily at 10pm. Set and forget it.
rsync -altgvb /var/data/ /home/user/backup
RSYNC SSH - COPIA A UN SERVER.
rsync -e ssh -altgvb /data/ root@192.168.0.1:/home/user/backup
- Hasta aqui todo esta bien, pero si necesitamos hacer esto automaticamente cada hora mediante cron tenemos que lograr que ssh no nos pida contraseña. Para lograrlo realizamos el siguiente procedimiento:
Creamos una llave publica y una llave privada:
ssh-keygen -tdsa
Presionando solo enter en todas las preguntas que el comando anterior requiere vamos a tener nuestra llave publica en /home/usuario/.ssh/id_dsa.pub. Copiamos esta llave al servidor 192.168.0.1:
cd /home/usuario/.ssh/
cat id_dsa.pub | ssh bot@192.168.1.4 "cat - >> /home/bot/.ssh/authorized_keys"
Probamos que todo funcione haciendo:
ssh -l bot 192.168.1.4
Estas son las opciones de Rsync para entender mejor los comandos de arriba.
n no: no transferir solo mostrar lo que hay que hacer
# -a modo archivo (= -rlptDg)
# -r recursivo
# -l preservar soft links
# -p preservar permisos
# -t preservar fecha
# -D preservar dispositivos (solo root)
# -g preservar grupo
# -v modo verboso (-vv mas verboso)
# -z comprimir (si lo admite el servidor)
# -C ignorar archivos como lo hace CVS
# -u update: mantiene archivo destino si existe y es posterior
# -b backup: renombrar archivos destino preexistentes a extensión ~
# --stats imprimir estadisticas al final (solo si se ha puesto también -v)
# --delete borrar archivos en destino si no existen
# -R path relativos (crear rutas completas en el destino)
./rsync.sh install [push | pull] [local_dir] [remote_user] [remote_host] [remote_dir] [remote_ssh_port]
./rsync.sh install pull /home/brett/ brett 192.168.1.2 /home/brett 2222
./rsync.sh run [push | pull] localhost:'/home/paul /media/sdb1/music' [remote_user] [remote_host] [remote_dir] [remote_ssh_port]
The ssh-copy-id command is useful for copying the public key.
ssh-copy-id -i
CLI (Command Line)
rsnapshot: a filesystem snapshot utility for making backups of local and remote systems. The disk space required is just a little more than the space of one full backup, plus incrementals. (My program does not use incrementals).
Code:
sudo aptitude install rsnapshot
Vocabulary
* ssh: a network protocol that allows data to be exchanged using a secure channel (encryption) between two computers
* rsync: a software application for Linux which synchronizes files and directories from one location to another using minimal bandwidth (only transfers files (or parts of files) that don't exist)
* mirror: an exact copy of a data set
* push: to send (or give) data from one computer to another
* pull: to receive (or ask) for data from one computer to another
Let's get started
It has several flags and options, but some are hard-coded, so you may have to edit the script by hand.
Options
General usage:
Quote:
./rsync.sh ['uninstall' | 'install' | 'run'] ['push' | 'pull'] [local_dir] [remote_user] [remote_host] [remote_dir] [remote_ssh_port]
Note: '[remote_ssh_port]' is usually 22 unless you change it from the default. If you don't know how to change the ssh port, its more than likely 22.
install
Use this option if you want to setup an automated, nightly backup between one computer and another.
Arguments:
Quote:
./rsync.sh install [push | pull] [local_dir] [remote_user] [remote_host] [remote_dir] [remote_ssh_port]
Example:
Quote:
./rsync.sh install pull /home/brett/ brett 192.168.1.2 /home/brett 2222
* Creates the following directories: $HOME/bin, $HOME/cron, $HOME/logs
* Creates 4096-bit RSA encryption key (illegal in the USA I think)
* Installs file to directories above
uninstall
Use this option if you want to remove a previously installed setup.
Arguments:
Quote:
./rsync.sh uninstall [remote_user] [remote_host]
Example:
Quote:
./rsync.sh uninstall brett 192.168.1.2
* Removes cron-job
* Removes RSA key
run
Use this option if you want to run the program without installing anything. Good to use as a test and on a single-needs basis.
Arguments:
Quote:
./rsync.sh run [push | pull] [local_dir] [remote_user] [remote_host] [remote_dir] [remote_ssh_port]
Example:
Quote:
./rsync.sh run pull /home/brett/ brett 192.168.1.2 /home/brett 2222
* Runs rsync with your parameters
That turns out to be really easy. If you’ve got ssh, then you’ve probably got ssh-keygen, which exists for the sole purpose of generating public and private keys, which when created without a passphrase can be used for password-free logins. So I ran ssh-keygen to generate a 2048 bit RSA key without a passphrase (aka a passphraseless key). I could also have generated a 1024 bit DSA key. I’m not sure I understand the difference. I’m not sure it matters.
ssh-keygen -b 2048
Inside ~/.ssh, ssh-keygen created two standard files, id_rsa and id_rsa.pub, the private and public keys respectively. The next and final step is to copy and “install” the public key on my backup server (192.168.0.100).
ssh-copy-id -i ~/.ssh/id_rsa.pub jwatt@192.168.0.100
ssh-copy-id uses ssh to copy the public key to the remote server and appends it to the ~/.ssh/authorized_keys file. Of course I didn’t know about ssh-copy-id when I started, so I just scp-ed the file over and pasted the public key into the authorized_keys file.
At which point I could use ssh to login without a password! ssh knows to automatically check for the existence of the id_rsa private key and try logging in with that.
ssh 192.168.0.100
Hot damn! That alone makes me want to start distributing my public key around to every server I access regularly. Of course the other benefit (and the whole point of this post!) is that now I’ll also be able to cron an rsync backup without requiring a password.
My ideal backup is a relatively current mirror of my home directory. I’m not looking for modified file snapshots or entire bootable filesystem images, I just want to know that if my hard drive crashes, most of my data (especially the photos) is recoverable. To that end, my rsync needs are relatively simple, though it took some tweaking to get to this point:
rsync -aze ssh --delete --exclude=".*/" /home/jwatt/ jwatt@192.168.0.100:/home/jwatt/backup/x23/
The -a option means archive files—it’s really an alias for a lot of other options having to do with maintaining permissions and timestamps, etc. The -z option uses compression when transferring files. The -e ssh option tunnels the file transfer over an encrypted ssh connection. The --delete option deletes any destination files that have been deleted from the source. The --exclude=".*/" option skips hidden files and directories. Finally the last two parts are the source (in this case everything under my home directory) and the destination I’ve already set up on my backup server.
And that’s it. I added it to my cron to run daily at 10pm. Set and forget it.
Suscribirse a:
Entradas (Atom)