Forwarded port seemingly not working (edit: it was snort)

I am at a loss to explain why I cannot access a device behind my router/firewall. It is running ssh on 43232. I setup the following rule which should cover it, yet when I attempt to connect from an external machine, the connection just hangs.

% ssh -v -p 43232 69.x.x.x
debug1: Reading configuration data /home/facade/.ssh/config
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Connecting to 69.x.x.x port 43232
debug1: identity file /home/facade/.ssh/id_ed25519 type 3
debug1: identity file /home/facade/.ssh/id_ed25519-cert type -1
debug1: Local version string SSH-2.0-OpenSSH_9.3

Yet connecting from a machine behind the router/firewall works just fine. There is nothing on the box running ssh that would be blocking connections.

Couldn't hurt to run tcpdump (optional package; can be installed) on the OpenWRT box, to see what - if anything - is arriving at and leaving OpenWRT.

have you verified that you have a true public IP address on your OpenWrt WAN? What are the first 2 octets as reported in the IPv4 Upstream section of the main OpenWrt LuCI status page?

1 Like

Any hits on the rules?

nft list ruleset | grep -B1 reborn
1 Like

Just to be sure: On which port is your internal SSH daemon listening? If it's the standard "22", then you're missing the destination port.

This is how my port-forward looks like:

I explicitly configured a destination port, and I enabled an additional SSH daemon instance on port 6000 on the internal machine.

1 Like

What is the proper syntax?
I ran this and tried to connect... 6 packets received by filter...??:

# tcpdump -evni any udp port 23556
tcpdump: data link type LINUX_SLL2
tcpdump: listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
^C
0 packets captured
6 packets received by filter
0 packets dropped by kernel

Yes, the first 2 octets (the entire IP address) matches what my ddns also resolves to.

I changed the name of the rule to the target device to "rpib4" whereas reborn is another host behind the router. I also changed the target port to 23556.

# nft list ruleset | grep -B1 pi4
                ip saddr { 10.200.200.0/24, 192.168.1.0/24 } ip daddr 67.149.72.220 tcp dport 43232 dnat ip to 192.168.1.100:43232 comment "!fw4: ssh reborn (reflection)"
                ip saddr { 10.200.200.0/24, 192.168.1.0/24 } ip daddr 67.149.72.220 tcp dport 23556 dnat ip to 192.168.1.101:23556 comment "!fw4: rpi4b (reflection)"
--
                ip saddr { 10.200.200.0/24, 192.168.1.0/24 } ip daddr 192.168.1.100 tcp dport 43232 snat ip to 192.168.1.1 comment "!fw4: ssh reborn (reflection)"
                ip saddr { 10.200.200.0/24, 192.168.1.0/24 } ip daddr 192.168.1.101 tcp dport 23556 snat ip to 192.168.1.1 comment "!fw4: rpi4b (reflection)"
--
                meta nfproto ipv4 tcp dport 43232 counter packets 0 bytes 0 dnat ip to 192.168.1.100:43232 comment "!fw4: ssh reborn"
                meta nfproto ipv4 tcp dport 23556 counter packets 0 bytes 0 dnat ip to 192.168.1.101:23556 comment "!fw4: rpi4b"

It is setup on both 22 and 23556 (I restarted the daemon, and I can connect on 23556 from another device behind the router/firewall, just not from the WAN.

I also tried specifying both the source and destination ports but no change.

What is the rule in /etc/config/firewall?

SSH is tcp, not udp.

	option dest 'lan'
	option target 'DNAT'
	option name 'rpi4b'
	option src 'wan'
	option src_dport '23556'
	option dest_ip '192.168.1.101'
	option family 'ipv4'
	list proto 'tcp'

Darn it, you're right.

Running the correct tcpdump command now gives me tons of traffic to and from my external IP and target IP. So it seems that the forward is working as expected. I guess there is something eluding me running on the target box filtered or blocking...

1 Like

To make things more confusing, if I run tcpdump on box to which I am trying to connect just like I did on the router, I see tons of traffic to and from as well. So it's clearing arriving where it should.

1 Like

Well, my previous post was a bit myopic in my thinking. As I noodled on the problem a bit longer the solution hit me: I recently get snort working in IPS mode on my router. It was to blame, nothing wrong with OpenWrt on the remote network nor with the RPi4B I wanted to ssh into there either!

7/10-17:21:42.444949 [drop] [**] [1:13586:5] "APP-DETECT SSH server detected on non-standard port" [**] [Classification: Generic Protocol Command Decode] [Priority: 3] {TCP} x.x.x.x:23556 -> 10.9.8.101:36564

Glad snort is doing it's job :smiley:

@xxxx @efahl

4 Likes

It wasn't DNS? Wow, first time ever. :joy:

2 Likes

Good to hear. Exactly because of something like this I am for the possibility to create exception rules in the queue script before the queue :wink:

...do either of you guys @xxxx @efahl know how to make this snort rule use either !22 or !23556 or is it easier to just duplicate the line?

alert tcp $EXTERNAL_NET !22 -> $HOME_NET any ( msg:"APP-DETECT SSH server detected on non-standard port"; flow:to_client,established; content:"SSH-",depth 4,nocase; pcre:"/^SSH-[12]\.\d+/ims"; metadata:policy max-detect-ips drop; reference:url,www.ietf.org/rfc/rfc4251.txt; classtype:protocol-command-decode; sid:13586; rev:5; )

Maybe [1:21,23:65535] is how you say not 22, note square brackets.

https://docs.snort.org/rules/headers/ports

Or would it be easier to invert the action? Maybe add an earlier rule that does pass on 22 https://docs.snort.org/rules/headers/actions

I never wrote rules before... I just added this to the bottom of the rules file and it seems to work:

alert tcp $EXTERNAL_NET !23556 -> $HOME_NET any ( msg:"APP-DETECT SSH server detected on non-standard port"; flow:to_client,established;        content:"SSH-",depth 4,nocase; pcre:"/^SSH-[12]\.\d+/ims"; metadata:policy max-detect-ips drop; reference:url,www.ietf.org/rfc/rfc4251.txt;  classtype:protocol-command-decode; sid:13586; rev:5; )```

I'm batting 0.000 in my attempts at writing rules. I've tried to write a simple test rule to alert on IPv6 ping from anywhere to anywhere, which seems like it would be pretty simple, right? I've spent a couple hours on it and never gotten it to work. Maybe someday...

It was not necessary to write a new rule, it makes no sense because the rule only says that SSH does not run on the default port, it is easier to disable this rule in snort.lua for the target.

suppress =
{
{ gid = 1, sid = 13586, track = 'by_dst', ip = '10.9.8.101' },
}

I'd like the rule to block ssh traffic is not on port 22 or port 22556. I think your method would stop that entirely, no?