nftables don´t allow ssh - server

I have a ruleset in my server looking like this:
table inet firewall {
chain INBOUND {
type filter hook input priority filter; policy drop;
ct state established,related accept
ct state invalid drop
iif "lo" counter packets 0 bytes 0 accept
ip protocol icmp limit rate 4/second accept
ip6 nexthdr ipv6-icmp limit rate 4/second accept
ip protocol igmp limit rate 4/second accept
tcp dport 22 accept
log
}
chain FORWARD {
type filter hook forward priority filter; policy drop;
}
chain OUTBOUND {
type filter hook output priority filter; policy drop;
oif "lo" counter packets 35 bytes 1946 accept
tcp dport 22 accept
}
}
I´m not be able to connect from ssh on port 22 even although should be opened. If I type:
$ nft flush ruleset, then, 22 port allows connection.
What I´m doing wrong?

It seems to me that the rules in the "OUTBOUND" chain are the problem.
You have tcp dport 22 accept but I think that should be tcp sport 22 accept because when the SSH packets are outbound from your server they will have a source port of 22, not a destination port of 22.

Change your OUTBOUND chain to:
chain OUTBOUND {
type filter hook output priority filter; policy drop;
# Allow traffic from established and related packets, drop invalid
ct state vmap { established : accept, related : accept, invalid : drop }
# Allow loopback
oif "lo" accept
# Accepted ports out (DNS / DHCP / TIME / WEB for package updates / SMTP)
ct state new udp dport { 53, 67, 123, 547 } accept
ct state new tcp dport { 53, 80, 443, 587 } accept
log prefix "DROP_output: " limit rate 3/second
}
Not accepting related outbound connections stopped sshd from responding.
Always log dropped packets at the end of every default deny chain. Often when something is not working it is a firewall issue.

Related

TCP socket state become persist after changing IP address even configured keep-alive early

I met a problem about TCP socket keepalive.
TCP keep-alive is enabled and configured after the socket connection, and system has its own TCP keep-alive configuration.
'ss -to' can show the keep-alive information of the connection.
The network interface is a PPPOE device, if we ifup the interface, it will get a new ip address. And the old TCP connection will keep establish until keep-alive timeout.
But sometimes 'ss -to' shows that the tcp connection becomes 'persist', which will take long time (about 15 minutes) to close.
Following is the result of 'ss -to':
ESTAB 0 591 172.0.0.60:46402 10.184.20.2:4335 timer:(persist,1min26sec,14)
The source address is '172.0.0.60', but the network interface's actual address has been updated to '172.0.0.62'.
This is the correct result of 'ss -to':
ESTAB 0 0 172.0.0.62:46120 10.184.20.2:4335 timer:(keepalive,4.480ms,0)
I don't know why the "timer" is changed to 'persist', which makes keep-alive be disable.
In short: TCP keepalive is only relevant if the connection is idle, i.e. no data to send. If instead there are still data to send but sending is currently impossible due to missing ACK or a window of 0 then other timeouts are relevant. This is likely the problem in your case.
For the deeper details see The Cloudflare Blog: When TCP sockets refuse to die.

How to build forged ICMP "Destination Unreachable" Type 3 Code 4 packet

I have created forged destination unreachable ICMP with type 3 and code 4 (fragmentation needed and DF bit is set). My setup has Server, Client, and a switch between them. Ideally this ICMP gets generated by router/gateway but I'm generating this at client. I'm creating this ICMP using Scapy tool. Here is how I'm creating:
ip = IP()
icmp = ICMP()
# IP Packet sent to client
ip.dst = ip_server
ip.src = ip_client
ip.protocol = 1 #shows that ip header contains icmp as data
# icmp type 3 + code 4
icmp.type = 3
icmp.code = 4
mtu =1300
icmp.unused = mtu
#
# build original packet for ICMP ping request
#
ip_orig = IP()
ip_orig.src = ip_server
ip_orig.dst = ip_client
icmp_orig = TCP()
tcp_orig.sport = 50000
tcp_orig.dport = 50000
tcp_orig.seq= original sequence number
#
# send the packet
#
send (ip/icmp/ip_orig/tcp_orig)
Steps I'm following to demonstrate the effect of this ICMP:
1> Server and client are talking to each other using sockets
2> As soon as server accepts the connection, I'm giving a 60 seconds pause in the machine during which I disable all the TCP ACKs going out of client machine (because if server receives ACKs for the message it sent then it wouldn't respond to ICMP).
3> Server sends it first message to client but won't receive any ACKs and server keeps re-transmitting the message, meanwhile I inject an ICMP message as mentioned in the above scapy code: send (ip/icmp/ip_orig/tcp/orig). I'm reporting MTU 1300 in the icmp i'm sending.
4> Ideally Server should reduce it's MTU and sends message back to client with MTU size of 1300.
But Server keeps re-transmitting the message with MTU size 1500. Kindly help me with this.
Why is server not reducing its MTU? Am I doing something wrong in my demonstration? Any help would be greatly appreciated.
There are a few pointers I outlined in this answer and in its comments:
The specification requires that the original IP header that is encapsulated in the ICMP error message (i.e. ip_orig) is exactly identical to the one received. Therefore, setting just its source IP address and destination IP addresses (i.e. ip_orig.src and ip_orig.dst, respectively) is probably not enough.
The sequence number of the original TCP header that is encapsulated in the ICMP error message (i.e. tcp_orig.seq) should be set as well, since the specification requires that at least 8 bytes of the problematic packet's IP layer payload are included in the ICMP error message.
Verify that path MTU discovery is enabled and that the DF bit is set. You can enable path MTU discovery with sysctl -w net.ipv4.ip_no_pmtu_disc=0.
Verify that there isn't any firewall and/or iptables rule that blocks ICMP messages.

Snort Rule to Alert DNS that has ACK

What way can i write a rule to alert me of a DNS that has an ACK when it shouldnt? Im quite confused on this.
This is what i see in wireshark Acknowledgment Number: 0x000001a4 [should be 0x00000000 because ACK flag is not set]
But i want a rule that will alert me.
This rule below isnt working for me.
alert tcp any any -> 192.168.10.2 53 (msg:"MALFORMED DNS QUERY"; flags: A; ack:0; sid:10501;)
The above wont show in my alert log. But if i remove flags: and ack: it will.
When the ACK flag is set the acknowledgment number will never be "0", so this rule will not function as is.
Without "ack:" the only check in the rule is for an ACK flag set (rule header aside). If you are running DNS over TCP you will see the ACK flag set as a normal part of the TCP conversation i.e. each endpoint acknowledging received TCP segments.
What you're seeing in wireshark:
Acknowledgment Number: 0x000001a4 [should be 0x00000000 because ACK flag is not set]
Might be part of the expert info telling you that the acknowledgment number is non-zero when it should be (for instance when a tcp connection is initiated the first packet should only have the SYN flag set.)
I'm really not sure what you are trying to accomplish here.

TCL script cannot configure multicast socket

I'm working with tcl script under ubuntu 12.04, and I'm facing some problem when I try to configure a multicast socket. What I'm trying to do is to forward traffic from some socket to a multicast one, but I don't know why although the multicast socket is created well,apparently; it isn't bound to the multicast group I want to.
This is the script I'm using
#!/bin/sh
# test.tcl \
exec tclsh "$0" ${1+"$#"}
package require udp
set multicastPort "50003"
proc connector {unicastIP multicastIP port {protocol tcp}} {
if { [string equal $protocol "tcp"] } {
socket -server serverTCP -myaddr $unicastIP $port
puts "tcp"
} elseif {[string equal $protocol "udp" ] } {
serverUDP $unicastIP $multicastIP $port
puts "udp"
}
}
proc serverUDP {unicastIP multicastIP port} {
global multicastPort
set socketUDP [udp_open $port]
puts " $unicastIP"
fconfigure $socketUDP -blocking false -translation binary -buffering none -remote [list $unicastIP $port]
#fileevent $socketUDP readable [list gettingData $socketUDP]
set multicastSocket [udp_open $multicastPort]
udp_conf $multicastSocket -ttl 4
fconfigure $multicastSocket -blocking false -translation binary -buffering none -mcastadd $multicastIP -remote [list $multicastIP $port]
fileevent $socketUDP readable [list forwarding $socketUDP $multicastSocket ]
#puts $socketUDP "hello!"
#flush $socketUDP
}
proc forwarding {socketSrc socketDst} {
set data [read -nonewline $socketSrc]
puts "Read data-> $data"
puts -nonewline $socketDst $data
puts "Written data-> [read -nonewline $socketDst]"
}
connector 127.0.0.1 224.0.1.1 50000 udp
vwait forever
However if I run the script and check out the ports in my system, the multicast port is not assigned the proper multicast IP as you can see
~$ netstat -ptnlu
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp 0 0 0.0.0.0:50000 0.0.0.0:* 3334/tclsh
udp 0 0 0.0.0.0:50003 0.0.0.0:* 3334/tclsh
Could anyone tell me the reason?
THanks in advance,
Regards!
AFAIK, that is OK. I have a multicast daemon in production using Tcl and its udp package, and netstat and ss tools also show me the socket as listening on the wildcard address.
"The trick" here, I suppose, is that multicasting is one level up the stack: joining a multicast group is not merely opening a socket or an endpoint on the group address but rather sending a very real IGMP "join" message to the local transport segment (Ethernet, in most deployments) and further communicating with the nearby IGMP routers (again, on Ethernet, they're mostly switches).
So, in your case, just fire up tcpdump and see what it dumps when you start your program. A useful call to tcpdump looks something like this:
tcpdump -i eth0 -n 'igmp and host 224.0.1.1'
To observe UDP traffic exchanges use
tcpdump -i eth0 -n 'udp and host 224.0.1.1 and port 50000'

Socket Programming: bind() system call

While studying computer networks as the course subject, my concept was that operating system distinguishes a packet based on the destination port and delivers it to application which is running on that port.
Later I came to know that we can connect to two different destinations (DestinationIP:DestinationPort) using the same source(SourceIP:SourcePort).
tcp 0 0 192.168.1.5:60000 199.7.57.72:80 ESTABLISHED 1000 196102 10179/firefox
tcp 0 0 192.168.1.5:60000 69.192.3.67:443 ESTABLISHED 1000 200361 10179/firefox
tcp 0 0 192.168.1.5:60000 69.171.234.18:80 ESTABLISHED 1000 196107 10179/firefox
tcp 0 0 192.168.1.5:60000 107.21.19.182:22 ESTABLISHED 1000 196399 10722/ssh
tcp 0 0 192.168.1.5:60000 69.171.234.18:443 ESTABLISHED 1000 201792 10179/firefox
tcp 0 0 192.168.1.5:60000 69.192.3.34:443 ESTABLISHED 1000 200349 10179/firefox
tcp 0 0 127.0.0.1:4369 127.0.0.1:51889 ESTABLISHED 129 12036 1649/epmd
tcp 0 0 192.168.1.5:60000 69.192.3.58:443 ESTABLISHED 1000 200352 10179/firefox
tcp 0 0 192.168.1.5:60000 74.125.236.88:80 ESTABLISHED 1000 200143 10179/firefox
tcp 0 0 192.168.1.5:60000 174.122.92.78:80 ESTABLISHED 1000 202935 10500/telnet
tcp 0 0 192.168.1.5:60000 74.125.236.87:80 ESTABLISHED 1000 201600 10179/firefox
Going little more into depths, I came to know that if an application uses bind() system call to bind a socket descriptor with a particular IP and port combination, then we can't use the same port again. Otherwise if a port is not binded to any socket descriptor, we can use the same port and IP combination again to connect to a different destination.
I read in the man page of bind() syscall that
bind() assigns the address specified to by addr to the socket referred to by the file descriptor sockfd.
My question are:
When we don't call bind() syscall generally while writing a client program then how does the OS automatically selects the port number.
When two different applications use the same port and IP combination to connect to two different servers and when those servers reply back, how does the OS finds out that which packet needs to be redirected to which application.
When we don't call bind() syscall generally while writing a client
program then how does the OS automatically selects the port number
The OS picks a random unused port (not necessarily the "next" one).
how does the OS finds out that which packet needs to be redirected to
which application
Each TCP connection is identified by a 4-tuple: (src_addr, src_port, dst_addr, dst_port) which is unique and thus enough to identify where each segment belongs.
EDIT
When we don't call bind() syscall generally while writing a client
program then how does the OS automatically selects the port number.
Sometime before "connecting" in the case of a TCP socket. For example, Linux has the function inet_csk_get_port to get an unused port number. Look for inet_hash_connect in tcp_v4_connect.
For 1: OS just picks the next available port.
For 2: It is done based on the dst port. Client applications will connect to same server over different client ports
I think for a client program OS maintains a table with socket fd(opened by client) and server IP+port after establishment of TCP connection.So whenever server replies back, OS can pick up the socket fd against the particular server IP+PORT and data is written onto the socket fd. So server reply can be available to the client on this particular socket fd.