Open external port into ipFire firewall?

In my application, I want to setup an ssh reverse tunnel. The reverse tunnel is initiated by a unsecure remote client (ET phone home). The reverse tunnel stays live 24/7, but I only need occasional access from my end. I need to open a port on the RED interface to allow the reverse tunnel to connect to ipFire…

Typically ssh connections are forwarded from the firewall to a specific machine on the Green/Blue networks. I do not want to do that. If a bad actor gains access to the remote client and hacks in to get access to the machine, they will then be able to get onto my GREEN network.

My solution to this problem is to create a special user within ipFire called abysm using the commands:

$ useradd abysm -m -d /home/abysm -s /bin/true
$ usermod -p ‘*’ abysm

This creates a user with no shell access, and no password login access. Even if a hacker can tunnel to this user, they can’t go any further. The reverse tunnel terminates at the abysm user within ipFire.

The remote client initiates a reverse tunnel to the user absym. From my (any) pc on the green/blue network, I setup a forward tunnel that connects with the absym user. The tunnels are configured to connect end-to-end and act like they are seamless. It creates a tunnel from my pc to the remote client.

This is highly secure. This method creates a reverse tunnel that ends at a dead-end with no access to any ipFire protected network or machine. The tunnel is only open when I connect a forward tunnel to the end of the reverse tunnel. It would be a lot easier to explain if I could attach an diagram, but it worked well on ipCop. Now I need to replicate the setup on ipFire.

On the “Firewall Rules” page of ipFire, I have set the following entries:
Standard networks RED
No tick in Use Network Translation (NAT)
Firewall RED

At least one reason this won’t work is because none of the above opens the pin-hole destination port. I can’t find anywhere in the ipFire user interface/documentation where I can specify an incoming port to open without NAT. I am not forwarding the port.

If this is not something I can set up on the ipFire WUI, do I need to use iptables CLI??

Hi @dazz.

I had the same problem due to the accesses that Users from Home made through RDP from their private computers (which, being private, I do not have them under control), since any network virus can infect the internal network through OpenVPN. To do this, I created this rule:

In this way, this type of Users can only communicate through RDP.

I don’t know if this will work for you, but it is the solution I adopted. Maybe someone who knows more will shed more light on us.

You will tell us


Hi Roberto

I use a reverse tunnel from the remote clients because the clients are within a Mobile phone network. The Telcos all have a firewall between the Internet and their RF network to keep out traffic. A reverse tunnel from the remote client creates a pinhole through the firewall without any knowledge of the firewall.

I use OpenVPNs to allow remote connection into my DMZ so that is an option I know of. The key feature of SSH tunnels is that they are suitable and configurable for occasional intermittent connections. This includes the ability to terminate the reverse tunnel inside ipFire.

SSH is a very powerful tool that has a lot of features that are a bit like Lego blocks. Simple features can be combined and connected to make something complex.

I figured out how to include an image.
The diagram shows the overall configuration and the SSH commands. It does not include the AutoSSH setup.
I need to be able to open port 12345 (not the port I actually use) in ipFire.

The actual setup is even more complex because remotebox is a Wifi AP with SSH connections to local clients. Once I am connected with remotebox, I open ssh wifi connections to the clients.

1 Like

I should probably explain what the diagram shows.

The remotebox builds a reverse tunnel that is aimed at my home ip address obtained with a dynamic DNS service.
The primary tunnel is aimed at the abysm user within the firewall.
All traffic passes through port 12345 at the firewall.

The remotebox also builds two reverse tunnels within the primary tunnel.

When I want to connect from my desktop pc to the remotebox, I build two forward tunnels to the absym user. The important detail is that Port 9012 and 9011 are paired to the incoming reverse tunnels. They connect seamlessly. The user abysm is simply the junction point where the tunnels meet.

So when I want to connect to the CLI of the remotebox, I simply ssh to the localhost through port 9010. That traffic emerges at port 22 on remotebox.

When I want to connect a webserver running on the remotebox, I point my web browser to port 9009 on my home desktop. That traffic emerges at port 8999 on remotebox.

In this way, I can simultaneously run a web browser and be on the CLI of the remotebox. The tunnels are invisible to applications I run on the desktop.

If needed, I could easily add additional tunnels within the primary tunnel. Traffic for all tunnels passes through the single port 12345 of the firewall.

The diagram does not show the autossh config I use to maintain the reverse tunnel.

So the problem I have is opening port 12345 on ipFire, and directing all traffic to the user abysm.

1 Like

So without any obvious (to me) way of opening a port in ipFire, I have resorted to iptables at the CLI. This is what I have figured out.

At the CLI of ipFire enter:

$ iptables -A INPUT -p tcp --dport 12345 -j ACCEPT

$ iptables -A OUTPUT -p tcp --dport 12345 -j ACCEPT

Save the rules in Ubuntu

$ iptables-save

List the rules:

$ iptables –nL | grep 12345

These rules open port 12345 on every interface. When I look at the list of interfaces I see:

  • red0,
  • red0.10
  • ppp0 and,
  • tun0

so I think I need to add -I red0 to the commands to open the port on the red interface.

I haven’t worked with iptables before, so I could easily have got something wrong, but I think this is a viable workaround.

1 Like

I think you should be able to create the rule you are proposing from IPFire web user interface. Source, red; destination firewall (all), protocol: TCP, port 12345, accept.

could you explain what you mean by the word “reverse” in your design? I find it fascinating but I have problems understanding the big picture.

That looks like it should do it. I am assuming the source port will be the 12345 at the RED interface.

It took me a long time to understand ssh well enough to do what I am doing but I am not an expert.

The way that I think of reverse/forward is that they define the tunnel entrance.
With a forward tunnel, the end that issues the command to build the tunnel is also the entrance.

So the command issued on the laptop:

ssh ipfire.localdomain -N -l abysm
-L 9010:ipfire.localdomain:9011
-L 9009:ipfire.localdomain:9012
–p 12345

builds two forward (Local) tunnels. The entrances to these tunnels are 9010 and 9009.
So to connect to these tunnels, specify one of those ports.
The exits are at 9011 and 9012.

For a reverse tunnel, the entrance is at the far end. So the tunnels built with the command:

ssh -N -l abysm
-R 9011:localhost:22
-R 9012:localhost:8999
–p 12345

The entrances are ports 9011 and 9012.
These two ports exist within ipFire, and they automatically connect to the forward tunnel exits with the same port numbers.

So when I issue a command from the laptop, it goes forward into the port 9010 and exits port 9011. This connects to the reverse entrance of the next tunnel also at port 9011 and exits at port 22.

Note that the user abysm has no active role in this.

I hope that helps.

@dazz Thank you, I learned a lot from you. Now reading again your posts I realize that they are well written and I should have understood your design from the beginning, but I could not just because I had the wrong mental framing. I was thinking the opposite of what you wanted, meaning that the laptop was on the WAN and it wanted to connect to your LAN, protected by IPFire.

To summarize, you want to connect from your laptop inside your LAN in the green or Blue zone, to a remote access point, on the red side of IPFire, which is running some web application. You want to have two encrypted connections, one for a console access and the other for web application. You establish a pair of semi-permanent reverse tunnels from the access point to the red zone of IPFire, and a pair of forward ones from the green or blue side of IPFire, using IPFire (with a user with no shell access) to join the two pairs of tunnels. Is that correct?

If yes, I am not sure whether you need only one rule in IPFire or two. Normally, the connections from the green side are not filtered. However my uncertainty comes from the fact that the forward tunnel is not really going to the red, but goes to the firewall (IPFire). Possibly (not sure) you need to setup also a second rule like this:

Source: green
Destination: Firewall
Protocol: TCP, Port 12345

The other doubt that I have concerns the rule from the red side. Are you sure the source should be the firewall? Maybe the source should be the RED network. I am not sure.

Thank you again for teaching me something that I did not know before.

@cfusco Your summary is correct.

I need to experiment with the rules. In this application I want to route traffic from port 12345 to an internal port that belongs to the user absym. The risk is that the remotebox is entirely unprotected from any hacker. The assumption is that a hacker will gain full control of the remotebox. The objective is to minimise the access a remote hacker could gain to my internal networks (GREEN/BLUE/ORANGE) It is undesirable for incoming traffic on port 12345 to be forwarded directly to the blue/green/orange networks.

Ideally I would like a rule that uses port 12345 as a source, and the user absym as the destination. I don’t believe that is possible with iptables because it doesn’t know about users. The next best thing might be to specify a destination (ip?) within ipFire. I am thinking that destination could be RED. That would provide an ip address that iptables would understand. It would also keep the port 12345 traffic off ALL of the networks. The traffic would be confined to the tunnels created from the laptop.

One of the major advantages of terminating the primary tunnel within ipFire (and not at a specific machine = normal practice) is that If I suspect the remotebox has been compromised, I can connect to the remotebox with a laptop on the ipFire DMZ network. That would limit exposure to the laptop.

Effectively I am doing ssh multiplexing at the command line. The link shows how to use control sockets. I found this link long after I figured out my own method. I have not experimented with ssh control sockets but it looks promising. It would require experimentation to know if it works with unreliable network connections.

ssh is a really powerful tool, but I have also found its potential difficult to understand and identify.

I am working on providing external access from the Internet to a secure user abysm created within ipFire as described in the previous posts.

I read the ipFire instructions on opening external access to enter values as shown here:

The result is the rule shown here:

When I run netstat to look at open ports, I get the following which shows port 24837 is not open. The rule has not been applied.
ipfire netstat

When I run # route it also shows the rule has not been applied.
When I run # netstat -na | grep :24837 to search for any rule with the right port, I get a null response.

So then I tried creating a rule from the terminal with the command:
# iptables -A INPUT -p tcp --dport 24837 -j ACCEPT

and repeated the tests above. Same results.

When I run # iptables -S | grep 24837 I get the following results:
-A INPUTFW -d -i ppp0 -p tcp -m tcp --dport 24837 -m limit --limit 10/sec --limit-burst 20 -j LOG --log-prefix "INPUTFW " -A INPUTFW -d -i ppp0 -p tcp -m tcp --dport 24837 -j ACCEPT
The first rule looks like it came from ipFire. The second rule, I entered manually.

Note I also rebooted the system multiple times just to ensure all rules would be applied.

Next I tried accessing the abysm user from the Internet. I have a stand-alone laptop connected to my mobile phone hotspot. I then access the internet to get external access to ipFire. I use the Internet ip shown on the home page of ipFire (no dynamic DNS service is used in testing).

I run the command: $ ssh -v -p24837 -N -i id_ecdsa abysm@123.456.789.0
I get a connection refused reponse.

When I look on the ipFire logs, I cannot see the attempted login.

I am now stuck. What should I do next?

your firewall rule red to red makes no sence to me.
here is a rule for a Minecraft server

I agree, it looks like nonsense but it follows my understanding of the ipFire user instructions.
The difference is the Source = Red + port (Internet), Destination = Red (ipFire)

For comparison, ipCop WUI looked like this:

Which makes much more sense because it is then Source =Red , Destination = ipCop Service.

Another key difference is that ipCop allowed a user to create a custom service. This makes the Current Rules table much easier to read and user friendly. The custom service was a single setup that allowed for use many times.

Your example shows.
Source any
Destination firewall.

You can make service groups in ipfire.

Yes, I looked at that, but that requires knowledge of the source (host) ip, which would be OK if the source ip was fixed, but it isn’t.

I have just tried making a connection from the Internet via port 222. It worked, so that definitely confirms the blockage is the port 24837 and associated rule. Neither the WUI generated rule, or my manual one work. My knowledge of iptables etc is light.

The setup I am aiming for terminates the incoming connection at the abysm user within ipFire. The abysm user is unusable. An intruder could have full access to the remote host, ssh keys, passwords etc and still be blocked by the abysm user.

I am going to further improve security using the Match User feature of ssh to limit external access logins to the abysm user. This will prevent a break-in using the root account.

I found the page on ipFire where custom services can be created. Nice.

OK I have found that being able to Add Service is no help to me because when I add a new iptables rule, I cannot select a service.

I have tried a different rule. This one aims to connect RED port 24837 to RED port 222, the ssh port.

When I run the command on the remote host:
# ssh -N -p222 -v abysm@123.456.789.0
The connection is accepted and made.

When I run the command on the remote host:
# ssh -N -p24837 -v abysm@123.456.789.0
The connection is refused.

Looking at the ipFire Wiki here: Creating and External Access Rule I followed the example to input these settings:

Again, when I specify the port 24837, the connection is refused. Although I have ticked to Logging box, I don’t see any of my attempts in the ipFire logs. I am running out of options to try.

The ssh server in IPFire is configured to only accept connections from port 222 or 22 depending on the setting on the SSH Access menu page so the second command fails because you are using port 24837 which ssh does not recognise but the first command works fine.

For that to work you would need to add another line in the /etc/sshd_config file under the existing Port 222 line that reads

Port 24837

That change will be saved in any backup but if you press the save button on the SSH Access WUI menu page then the file will be overwritten based on the settings on that page which won’t include your additional port.

For the reasons you have stated, amending /etc/sshd_config is the option of last resort. I was hoping to effectively shift the port from 24837 down to 222 within ipFire to match the config of ssh. I haven’t been able to do this within ipFire.

Port 24837 is only for use with the abysm user, so I am going to experiment with adding port to 24837 to ~/.ssh/config. Placing that port in the ~/.ssh/config should hopefully make it immune to changes to /etc/sshd_config. Not sure if that will work until I try it.