Here’s the setup:

  • Fedora 41 Server host
  • Libvirt/QEMU
  • Alma 9 guest running ssh

My goal is to forward ports from the guest to the host, but change them. I set up a hook(as in the libvirt docs) and it worked on my last server. My hook looks like:

#!/bin/bash

if [ "${1}" = "Jellyfin" ]; then

   # Update the following variables to fit your setup
   GUEST_IP=192.168.101.4
   GUEST_PORT=22
   HOST_PORT=2222

   if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
    /sbin/iptables -D FORWARD -o virbr1 -p tcp -d $GUEST_IP --dport $GUEST_PORT -j ACCEPT
    /sbin/iptables -t nat -D PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
   fi
   if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
    /sbin/iptables -I FORWARD -o virbr1 -p tcp -d $GUEST_IP --dport $GUEST_PORT -j ACCEPT
    /sbin/iptables -t nat -I PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
   fi
fi

However, when I ssh to my server:2222, it doesn’t work, “Connection refused.” I can ssh from inside my server to my guest’s ip address, so I know it’s not an issue with ssh itself. The guest’s iptables rules are:

-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT

so that’s probably not the issue.

My server’s iptables rules include:

-A FORWARD -d 192.168.101.4/32 -o virbr1 -p tcp -m tcp --dport 22 -j ACCEPT

, so it appears the forwarding happened, but an nmap scan reveals the port is closed:

2222/tcp closed EtherNetIP-1

I’m baffled by this issue. Any help would be greatly appreciated!

  • AndrasKrigare@beehaw.org
    link
    fedilink
    arrow-up
    2
    ·
    edit-2
    3 days ago

    Sorry, I was looking more specifically at that DNAT rule

    8   480 DNAT       6    --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:2222 to:192.168.101.4:22
    

    That rule exists in the host 192.168.86.73, correct? And from the guest, 192.168.101.4 you are attempting to ssh into 192.168.86.73:2222?

    It might not be your issue (or only issue), but that DNAT rule says that if a connection comes in on port 2222, instead send it to 192.168.101.4:22. So 192.168.101.4->192.168.86.73:2222->192.168.101.4:22. I would have thought you’d want it to be a DNAT to 192.168.86.73, functionally doing port bending, so it goes 192.168.101.4->192.168.86.73:2222->192.168.86.73:22.

    That doesn’t explain the connection refused, though, based on what you’ve said; there’s some fringe possibilities, but I wouldn’t expect for your setup if you hadn’t said (like your ~/.ssh/ssh_config defining an alternate ssh port for your guest OS than 22). It’s somewhat annoying, but it might be worthwhile to do a packet capture on both ends and follow exactly where the packet is going. So a

    tcpdump -v -Nnn tcp port 22 or tcp port 2222

    • potentiallynotfelixOP
      link
      fedilink
      arrow-up
      1
      ·
      3 days ago

      yes, the host is 192.168.86.73 and it has that dnat rule.

      And from the guest

      Assuming you meant from the host, I am sshing directly to 192.168.101.4 instead of to 192.168.86.73:2222.

      The third paragraph doesn’t make sense to me. I am using port 22 on my host(192.168.86.73) for it’s own ssh.

      tcpdump returns this when I ssh to port 2222:

      20:32:29.957942 IP (tos 0x10, ttl 64, id 28091, offset 0, flags [DF], proto TCP (6), length 60)
          192.168.86.23.53434 > 192.168.86.73.2222: Flags [S], cksum 0x5d75 (correct), seq 1900319834, win 64240, options [mss 1460,sackOK,TS val 3627223725 ecr 0,nop,wscale 7], length 0